Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pkix/src/main')
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/cert/CertUtils.java246
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/cert/X509AttributeCertificateHolder.java366
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/cert/X509CertificateHolder.java327
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/cert/X509v1CertificateBuilder.java83
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java138
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/cert/X509v2CRLBuilder.java231
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/cert/X509v3CertificateBuilder.java177
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/cert/crmf/EncryptedValueParser.java103
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/cert/crmf/FixedLengthMGF1Padder.java120
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/cms/CMSTypedStream.java85
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/operator/bc/OperatorUtils.java16
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/tsp/TimeStampToken.java391
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/tsp/TimeStampTokenInfo.java112
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedData.java201
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java204
-rw-r--r--pkix/src/main/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java88
-rw-r--r--pkix/src/main/j2me/org/spongycastle/cert/CertUtils.java246
-rw-r--r--pkix/src/main/j2me/org/spongycastle/cert/X509AttributeCertificateHolder.java366
-rw-r--r--pkix/src/main/j2me/org/spongycastle/cert/X509CertificateHolder.java327
-rw-r--r--pkix/src/main/j2me/org/spongycastle/cert/X509v1CertificateBuilder.java83
-rw-r--r--pkix/src/main/j2me/org/spongycastle/cert/X509v2AttributeCertificateBuilder.java138
-rw-r--r--pkix/src/main/j2me/org/spongycastle/cert/X509v2CRLBuilder.java231
-rw-r--r--pkix/src/main/j2me/org/spongycastle/cert/X509v3CertificateBuilder.java177
-rw-r--r--pkix/src/main/j2me/org/spongycastle/cert/crmf/EncryptedValueParser.java103
-rw-r--r--pkix/src/main/j2me/org/spongycastle/cert/crmf/FixedLengthMGF1Padder.java120
-rw-r--r--pkix/src/main/j2me/org/spongycastle/cms/CMSTypedStream.java85
-rw-r--r--pkix/src/main/j2me/org/spongycastle/operator/bc/OperatorUtils.java16
-rw-r--r--pkix/src/main/j2me/org/spongycastle/tsp/TimeStampToken.java391
-rw-r--r--pkix/src/main/j2me/org/spongycastle/tsp/TimeStampTokenInfo.java112
-rw-r--r--pkix/src/main/j2me/org/spongycastle/tsp/cms/CMSTimeStampedData.java201
-rw-r--r--pkix/src/main/j2me/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java204
-rw-r--r--pkix/src/main/j2me/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java88
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java357
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/AttributeCertificateIssuer.java147
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/CertException.java27
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/CertIOException.java29
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/CertRuntimeException.java19
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/CertUtils.java244
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java366
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/X509CRLEntryHolder.java144
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java317
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java327
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/X509ContentVerifierProviderBuilder.java14
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/X509ExtensionUtils.java132
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/X509v1CertificateBuilder.java101
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java162
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/X509v2CRLBuilder.java266
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java195
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/bc/BcX509ExtensionUtils.java91
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/bc/BcX509v1CertificateBuilder.java33
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/bc/BcX509v3CertificateBuilder.java51
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/cmp/CMPException.java24
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/cmp/CMPRuntimeException.java19
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/cmp/CMPUtil.java26
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateConfirmationContent.java41
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateConfirmationContentBuilder.java78
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateStatus.java60
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/cmp/GeneralPKIMessage.java82
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessage.java198
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessageBuilder.java306
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/cmp/RevocationDetails.java36
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/cmp/RevocationDetailsBuilder.java59
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/AuthenticatorControl.java57
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/CRMFException.java19
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/CRMFRuntimeException.java19
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/CRMFUtil.java42
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessage.java309
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessageBuilder.java279
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/Control.java24
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValueBuilder.java133
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValuePadder.java24
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValueParser.java103
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/PKIArchiveControl.java104
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/PKIArchiveControlBuilder.java78
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACBuilder.java199
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueGenerator.java41
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueVerifier.java43
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValuesCalculator.java15
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java75
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/RegTokenControl.java57
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/ValueDecryptorGenerator.java10
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java121
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/CRMFHelper.java450
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java84
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java57
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaEncryptedValueBuilder.java26
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java29
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java120
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java136
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java69
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/CertHelper.java17
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/DefaultCertHelper.java14
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaAttrCertStore.java62
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaAttributeCertificateIssuer.java32
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaCRLStore.java63
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaCertStore.java64
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java148
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX500NameUtil.java29
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509AttributeCertificateHolder.java26
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CRLConverter.java103
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CRLHolder.java26
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CertificateConverter.java116
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CertificateHolder.java26
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509ContentVerifierProviderBuilder.java50
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509ExtensionUtils.java145
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509v1CertificateBuilder.java48
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509v2CRLBuilder.java23
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java119
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/NamedCertHelper.java22
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/jcajce/ProviderCertHelper.java22
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPResp.java212
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPRespBuilder.java264
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/CertificateID.java156
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/CertificateStatus.java6
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPException.java27
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java259
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java199
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java141
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPRespBuilder.java59
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPUtils.java64
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/Req.java25
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/RespData.java52
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/RespID.java89
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/RevokedStatus.java55
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/SingleResp.java102
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/UnknownStatus.java12
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java18
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaCertificateID.java20
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java26
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/CertPath.java80
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/CertPathUtils.java21
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidation.java11
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationContext.java61
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationException.java24
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationResult.java66
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationResultBuilder.java14
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/validations/BasicConstraintsValidation.java103
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/validations/CRLValidation.java78
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/validations/CertificatePoliciesValidation.java146
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/validations/CertificatePoliciesValidationBuilder.java35
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/validations/KeyUsageValidation.java63
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/validations/ParentCertIssuedValidation.java127
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/path/validations/ValidationUtils.java11
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/selector/MSOutlookKeyIdCalculator.java422
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/selector/X509AttributeCertificateHolderSelector.java268
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/selector/X509AttributeCertificateHolderSelectorBuilder.java194
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java152
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java35
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java57
-rw-r--r--pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java72
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/AuthAttributesProvider.java8
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSAbsentContent.java49
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSAlgorithm.java51
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerationException.java32
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerator.java19
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedData.java78
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedGenerator.java13
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedData.java260
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataGenerator.java181
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataParser.java348
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java310
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedGenerator.java41
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSCompressedData.java107
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataGenerator.java74
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataParser.java72
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataStreamGenerator.java165
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSConfig.java34
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSContentInfoParser.java45
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSDigestedData.java136
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedData.java62
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedDataGenerator.java109
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedGenerator.java21
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedData.java206
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java131
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataParser.java208
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java305
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedGenerator.java75
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedHelper.java203
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSException.java32
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSProcessable.java21
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSProcessableByteArray.java55
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSProcessableFile.java80
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSProcessableInputStream.java50
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSReadable.java10
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSRuntimeException.java32
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSSecureReadable.java10
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java15
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java17
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java543
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java232
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataParser.java624
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataStreamGenerator.java486
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java239
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java253
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSSignerDigestMismatchException.java11
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSStreamException.java26
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSTypedData.java9
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSTypedStream.java86
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java335
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java11
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java99
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java161
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java46
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java121
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/KEKRecipient.java10
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/KEKRecipientId.java63
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/KEKRecipientInfoGenerator.java39
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/KEKRecipientInformation.java38
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipient.java14
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientId.java89
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInfoGenerator.java80
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInformation.java131
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipient.java10
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientId.java102
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientInfoGenerator.java58
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientInformation.java50
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/NullOutputStream.java28
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/OriginatorId.java118
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/OriginatorInfoGenerator.java54
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/OriginatorInformation.java95
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java20
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientId.java44
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientInfoGenerator.java122
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientInformation.java116
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/Recipient.java5
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/RecipientId.java31
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/RecipientInfoGenerator.java10
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/RecipientInformation.java181
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/RecipientInformationStore.java115
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java48
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/SignerId.java104
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java291
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java139
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/SignerInformation.java680
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/SignerInformationStore.java109
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/SignerInformationVerifier.java50
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/SignerInformationVerifierProvider.java16
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/SimpleAttributeTableGenerator.java25
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/BcCMSContentEncryptorBuilder.java124
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/BcKEKEnvelopedRecipient.java49
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/BcKEKRecipient.java33
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/BcKEKRecipientInfoGenerator.java19
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/BcKeyTransRecipient.java36
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/BcKeyTransRecipientInfoGenerator.java20
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/BcPasswordEnvelopedRecipient.java49
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/BcPasswordRecipient.java75
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/BcPasswordRecipientInfoGenerator.java45
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/BcRSAKeyTransEnvelopedRecipient.java50
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/BcRSAKeyTransRecipientInfoGenerator.java23
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/BcRSASignerInfoVerifierBuilder.java39
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/CMSUtils.java23
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/bc/EnvelopedDataHelper.java378
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/CMSUtils.java99
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/DefaultJcaJceExtHelper.java26
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java668
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaJceExtHelper.java18
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java55
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerId.java56
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java68
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java180
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoGeneratorBuilder.java202
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java150
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java24
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceAlgorithmIdentifierConverter.java64
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java160
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java155
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKAuthenticatedRecipient.java61
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKEnvelopedRecipient.java43
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java119
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipientInfoGenerator.java45
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeAuthenticatedRecipient.java57
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeEnvelopedRecipient.java45
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java184
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientId.java23
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java215
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransAuthenticatedRecipient.java60
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransEnvelopedRecipient.java43
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java156
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipientId.java57
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipientInfoGenerator.java87
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordAuthenticatedRecipient.java54
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordEnvelopedRecipient.java42
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordRecipient.java97
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java76
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/NamedJcaJceExtHelper.java31
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/ProviderJcaJceExtHelper.java32
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibCompressor.java24
-rw-r--r--pkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java116
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/CCPDRequestBuilder.java32
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/CCPDRequestData.java48
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/CPDRequestBuilder.java34
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/CPDRequestData.java40
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/DVCSConstructionException.java20
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/DVCSException.java28
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/DVCSMessage.java22
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/DVCSParsingException.java20
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequest.java134
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequestBuilder.java131
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequestData.java38
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequestInfo.java237
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/DVCSResponse.java74
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/MessageImprint.java38
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/MessageImprintBuilder.java35
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/SignedDVCSMessageGenerator.java45
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/TargetChain.java18
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/VPKCRequestBuilder.java76
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/VPKCRequestData.java51
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/VSDRequestBuilder.java49
-rw-r--r--pkix/src/main/java/org/bouncycastle/dvcs/VSDRequestData.java66
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/EACCertificateBuilder.java83
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/EACCertificateHolder.java88
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/EACCertificateRequestHolder.java88
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/EACException.java27
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/EACIOException.java29
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/jcajce/DefaultEACHelper.java14
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/jcajce/EACHelper.java11
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/jcajce/JcaPublicKeyConverter.java168
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/jcajce/NamedEACHelper.java22
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/jcajce/ProviderEACHelper.java22
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/operator/EACSignatureVerifier.java30
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/operator/EACSigner.java27
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/DefaultEACHelper.java14
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/EACHelper.java39
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/EACUtil.java5
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/JcaEACSignatureVerifierBuilder.java181
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/JcaEACSignerBuilder.java234
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/NamedEACHelper.java22
-rw-r--r--pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/ProviderEACHelper.java22
-rw-r--r--pkix/src/main/java/org/bouncycastle/mozilla/SignedPublicKeyAndChallenge.java139
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/EncryptionException.java23
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/MiscPEMGenerator.java209
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PEMDecryptor.java7
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PEMDecryptorProvider.java9
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PEMEncryptedKeyPair.java44
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PEMEncryptor.java11
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PEMException.java34
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PEMKeyPair.java26
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PEMKeyPairParser.java9
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PEMParser.java510
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PEMUtilities.java64
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PEMWriter.java69
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PKCS8Generator.java87
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PasswordException.java10
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/PasswordFinder.java9
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaMiscPEMGenerator.java98
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaPEMKeyConverter.java115
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaPEMWriter.java68
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaPKCS8Generator.java18
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java141
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java221
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcePEMDecryptorProviderBuilder.java54
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcePEMEncryptorBuilder.java78
-rw-r--r--pkix/src/main/java/org/bouncycastle/openssl/jcajce/PEMUtilities.java257
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyUnwrapper.java19
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyWrapper.java19
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/BufferingContentSigner.java70
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/ContentSigner.java27
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/ContentVerifier.java31
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/ContentVerifierProvider.java34
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java97
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeySizeProvider.java69
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java224
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java24
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/DigestCalculator.java36
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/DigestCalculatorProvider.java9
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/GenericKey.java41
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/InputDecryptor.java29
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/InputDecryptorProvider.java9
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/InputExpander.java29
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/InputExpanderProvider.java8
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/KeyUnwrapper.java11
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/KeyWrapper.java11
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/MacCalculator.java34
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/MacCalculatorProvider.java8
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/OperatorCreationException.java15
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/OperatorException.java24
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/OperatorStreamException.java21
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/OutputCompressor.java29
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/OutputEncryptor.java36
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/RawContentVerifier.java17
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/RuntimeOperatorException.java24
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java17
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/SignatureAlgorithmIdentifierFinder.java15
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/SymmetricKeyUnwrapper.java19
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/SymmetricKeyWrapper.java19
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/AESUtil.java34
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java13
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyWrapper.java13
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyUnwrapper.java51
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyWrapper.java60
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcContentSignerBuilder.java82
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcContentVerifierProviderBuilder.java144
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentSignerBuilder.java25
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java40
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java144
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java82
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcDigestProvider.java11
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java22
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java32
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentSignerBuilder.java24
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java39
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcSignerOutputStream.java47
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyUnwrapper.java49
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyWrapper.java51
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/CamelliaUtil.java36
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/OperatorUtils.java23
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/bc/SEEDUtil.java14
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java73
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java160
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java312
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java114
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java133
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java157
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/jcajce/JceGenericKey.java33
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java65
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java154
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java433
-rw-r--r--pkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorUtils.java25
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/MacDataGenerator.java49
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequest.java236
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequestBuilder.java156
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCS12MacCalculatorBuilder.java13
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCS12MacCalculatorBuilderProvider.java8
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCS12PfxPdu.java161
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCS12PfxPduBuilder.java179
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCS12SafeBag.java93
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCS12SafeBagBuilder.java76
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCS12SafeBagFactory.java58
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCS8EncryptedPrivateKeyInfo.java76
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCS8EncryptedPrivateKeyInfoBuilder.java54
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCSException.java27
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/PKCSIOException.java29
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequest.java42
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java28
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java54
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java40
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java66
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java77
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/bc/PKCS12PBEUtils.java153
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java115
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java38
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS12SafeBagBuilder.java45
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS8EncryptedPrivateKeyInfoBuilder.java15
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilder.java122
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilderProvider.java108
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java177
-rw-r--r--pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java179
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/GenTimeAccuracy.java60
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/TSPAlgorithms.java35
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/TSPException.java28
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/TSPIOException.java30
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/TSPUtil.java209
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/TSPValidationException.java34
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/TimeStampRequest.java267
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/TimeStampRequestGenerator.java163
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponse.java189
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponseGenerator.java353
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/TimeStampToken.java393
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenGenerator.java380
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenInfo.java121
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedData.java204
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataGenerator.java70
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java207
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java88
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/cms/ImprintDigestInvalidException.java21
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/cms/MetaDataUtil.java76
-rw-r--r--pkix/src/main/java/org/bouncycastle/tsp/cms/TimeStampDataUtil.java256
-rw-r--r--pkix/src/main/java/org/bouncycastle/voms/VOMSAttribute.java242
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/AttributeCertificateHolder.java357
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/AttributeCertificateIssuer.java147
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/CertException.java27
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/CertIOException.java29
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/CertRuntimeException.java19
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/CertUtils.java244
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/X509AttributeCertificateHolder.java366
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/X509CRLEntryHolder.java144
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/X509CRLHolder.java317
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/X509CertificateHolder.java327
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/X509ContentVerifierProviderBuilder.java14
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/X509ExtensionUtils.java132
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/X509v1CertificateBuilder.java101
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/X509v2AttributeCertificateBuilder.java162
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/X509v2CRLBuilder.java266
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/X509v3CertificateBuilder.java195
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/bc/BcX509ExtensionUtils.java91
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/bc/BcX509v1CertificateBuilder.java33
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/bc/BcX509v3CertificateBuilder.java51
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/cmp/CMPException.java24
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/cmp/CMPRuntimeException.java19
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/cmp/CMPUtil.java26
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/cmp/CertificateConfirmationContent.java41
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/cmp/CertificateConfirmationContentBuilder.java78
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/cmp/CertificateStatus.java60
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/cmp/GeneralPKIMessage.java82
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/cmp/ProtectedPKIMessage.java198
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/cmp/ProtectedPKIMessageBuilder.java306
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/cmp/RevocationDetails.java36
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/cmp/RevocationDetailsBuilder.java59
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/AuthenticatorControl.java57
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/CRMFException.java19
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/CRMFRuntimeException.java19
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/CRMFUtil.java42
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/CertificateRequestMessage.java309
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/CertificateRequestMessageBuilder.java279
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/Control.java24
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/EncryptedValueBuilder.java133
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/EncryptedValuePadder.java24
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/EncryptedValueParser.java103
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/PKIArchiveControl.java104
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/PKIArchiveControlBuilder.java78
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/PKMACBuilder.java199
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/PKMACValueGenerator.java41
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/PKMACValueVerifier.java43
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/PKMACValuesCalculator.java15
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java75
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/RegTokenControl.java57
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/ValueDecryptorGenerator.java10
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java121
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/CRMFHelper.java450
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java84
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java57
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaEncryptedValueBuilder.java26
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java29
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java120
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java136
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java69
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/CertHelper.java17
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/DefaultCertHelper.java14
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaAttrCertStore.java62
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaAttributeCertificateIssuer.java32
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaCRLStore.java63
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaCertStore.java64
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java148
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX500NameUtil.java29
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509AttributeCertificateHolder.java26
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CRLConverter.java103
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CRLHolder.java26
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CertificateConverter.java116
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CertificateHolder.java26
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509ContentVerifierProviderBuilder.java50
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java145
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java48
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java23
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java119
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/NamedCertHelper.java22
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/jcajce/ProviderCertHelper.java22
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/BasicOCSPResp.java212
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/BasicOCSPRespBuilder.java264
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/CertificateID.java156
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/CertificateStatus.java6
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPException.java27
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPReq.java259
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPReqBuilder.java199
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPResp.java141
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPRespBuilder.java59
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPUtils.java64
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/Req.java25
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/RespData.java52
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/RespID.java89
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/RevokedStatus.java55
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/SingleResp.java102
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/UnknownStatus.java12
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java18
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/jcajce/JcaCertificateID.java20
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java26
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/CertPath.java80
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/CertPathUtils.java21
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/CertPathValidation.java11
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationContext.java61
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationException.java24
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationResult.java66
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationResultBuilder.java14
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/validations/BasicConstraintsValidation.java103
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/validations/CRLValidation.java78
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/validations/CertificatePoliciesValidation.java146
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/validations/CertificatePoliciesValidationBuilder.java35
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/validations/KeyUsageValidation.java63
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/validations/ParentCertIssuedValidation.java127
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/path/validations/ValidationUtils.java11
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/selector/MSOutlookKeyIdCalculator.java422
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/selector/X509AttributeCertificateHolderSelector.java268
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/selector/X509AttributeCertificateHolderSelectorBuilder.java194
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/selector/X509CertificateHolderSelector.java152
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java35
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java57
-rw-r--r--pkix/src/main/java/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java72
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/AuthAttributesProvider.java8
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSAbsentContent.java49
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSAlgorithm.java51
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSAttributeTableGenerationException.java32
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSAttributeTableGenerator.java19
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSAuthEnvelopedData.java78
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSAuthEnvelopedGenerator.java13
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedData.java260
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedDataGenerator.java181
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedDataParser.java348
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedDataStreamGenerator.java310
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedGenerator.java41
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSCompressedData.java107
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSCompressedDataGenerator.java74
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSCompressedDataParser.java72
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSCompressedDataStreamGenerator.java165
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSConfig.java34
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSContentInfoParser.java45
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSDigestedData.java136
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSEncryptedData.java62
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSEncryptedDataGenerator.java109
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSEncryptedGenerator.java21
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedData.java206
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedDataGenerator.java131
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedDataParser.java208
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedDataStreamGenerator.java305
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedGenerator.java75
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedHelper.java203
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSException.java32
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSProcessable.java21
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSProcessableByteArray.java55
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSProcessableFile.java80
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSProcessableInputStream.java50
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSReadable.java10
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSRuntimeException.java32
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSSecureReadable.java10
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSSignatureAlgorithmNameGenerator.java15
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java17
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSSignedData.java543
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSSignedDataGenerator.java232
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSSignedDataParser.java624
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSSignedDataStreamGenerator.java486
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSSignedGenerator.java239
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSSignedHelper.java253
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSSignerDigestMismatchException.java11
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSStreamException.java26
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSTypedData.java9
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSTypedStream.java86
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSUtils.java335
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/CMSVerifierCertificateNotValidException.java11
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java99
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java161
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java46
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/DefaultSignedAttributeTableGenerator.java121
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/KEKRecipient.java10
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/KEKRecipientId.java63
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/KEKRecipientInfoGenerator.java39
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/KEKRecipientInformation.java38
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipient.java14
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipientId.java89
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipientInfoGenerator.java80
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipientInformation.java131
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/KeyTransRecipient.java10
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/KeyTransRecipientId.java102
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/KeyTransRecipientInfoGenerator.java58
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/KeyTransRecipientInformation.java50
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/NullOutputStream.java28
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/OriginatorId.java118
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/OriginatorInfoGenerator.java54
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/OriginatorInformation.java95
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/PasswordRecipient.java20
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/PasswordRecipientId.java44
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/PasswordRecipientInfoGenerator.java122
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/PasswordRecipientInformation.java116
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/Recipient.java5
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/RecipientId.java31
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/RecipientInfoGenerator.java10
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/RecipientInformation.java181
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/RecipientInformationStore.java115
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/RecipientOperator.java48
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/SignerId.java104
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/SignerInfoGenerator.java291
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/SignerInfoGeneratorBuilder.java139
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/SignerInformation.java680
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/SignerInformationStore.java109
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/SignerInformationVerifier.java50
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/SignerInformationVerifierProvider.java16
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/SimpleAttributeTableGenerator.java25
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/BcCMSContentEncryptorBuilder.java124
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/BcKEKEnvelopedRecipient.java49
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/BcKEKRecipient.java33
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/BcKEKRecipientInfoGenerator.java19
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/BcKeyTransRecipient.java36
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/BcKeyTransRecipientInfoGenerator.java20
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/BcPasswordEnvelopedRecipient.java49
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/BcPasswordRecipient.java75
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/BcPasswordRecipientInfoGenerator.java45
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/BcRSAKeyTransEnvelopedRecipient.java50
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/BcRSAKeyTransRecipientInfoGenerator.java23
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/BcRSASignerInfoVerifierBuilder.java39
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/CMSUtils.java23
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/bc/EnvelopedDataHelper.java378
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/CMSUtils.java99
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/DefaultJcaJceExtHelper.java26
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/EnvelopedDataHelper.java668
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JcaJceExtHelper.java18
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSelectorConverter.java55
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSignerId.java56
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java68
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java180
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSimpleSignerInfoGeneratorBuilder.java202
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java150
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java24
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceAlgorithmIdentifierConverter.java64
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java160
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java155
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKAuthenticatedRecipient.java61
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKEnvelopedRecipient.java43
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKRecipient.java119
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKRecipientInfoGenerator.java45
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeAuthenticatedRecipient.java57
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeEnvelopedRecipient.java45
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeRecipient.java184
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java23
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java215
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransAuthenticatedRecipient.java60
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransEnvelopedRecipient.java43
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransRecipient.java156
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java57
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransRecipientInfoGenerator.java87
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordAuthenticatedRecipient.java54
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordEnvelopedRecipient.java42
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordRecipient.java97
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java76
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/NamedJcaJceExtHelper.java31
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/ProviderJcaJceExtHelper.java32
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/ZlibCompressor.java24
-rw-r--r--pkix/src/main/java/org/spongycastle/cms/jcajce/ZlibExpanderProvider.java116
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/CCPDRequestBuilder.java32
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/CCPDRequestData.java48
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/CPDRequestBuilder.java34
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/CPDRequestData.java40
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/DVCSConstructionException.java20
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/DVCSException.java28
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/DVCSMessage.java22
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/DVCSParsingException.java20
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/DVCSRequest.java134
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/DVCSRequestBuilder.java131
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/DVCSRequestData.java38
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/DVCSRequestInfo.java237
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/DVCSResponse.java74
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/MessageImprint.java38
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/MessageImprintBuilder.java35
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/SignedDVCSMessageGenerator.java45
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/TargetChain.java18
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/VPKCRequestBuilder.java76
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/VPKCRequestData.java51
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/VSDRequestBuilder.java49
-rw-r--r--pkix/src/main/java/org/spongycastle/dvcs/VSDRequestData.java66
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/EACCertificateBuilder.java83
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/EACCertificateHolder.java88
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/EACCertificateRequestHolder.java88
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/EACException.java27
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/EACIOException.java29
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/jcajce/DefaultEACHelper.java14
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/jcajce/EACHelper.java11
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/jcajce/JcaPublicKeyConverter.java168
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/jcajce/NamedEACHelper.java22
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/jcajce/ProviderEACHelper.java22
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/operator/EACSignatureVerifier.java30
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/operator/EACSigner.java27
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/operator/jcajce/DefaultEACHelper.java14
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/operator/jcajce/EACHelper.java39
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/operator/jcajce/EACUtil.java5
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/operator/jcajce/JcaEACSignatureVerifierBuilder.java181
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/operator/jcajce/JcaEACSignerBuilder.java234
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/operator/jcajce/NamedEACHelper.java22
-rw-r--r--pkix/src/main/java/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java22
-rw-r--r--pkix/src/main/java/org/spongycastle/mozilla/SignedPublicKeyAndChallenge.java139
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/EncryptionException.java23
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/MiscPEMGenerator.java209
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PEMDecryptor.java7
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PEMDecryptorProvider.java9
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PEMEncryptedKeyPair.java44
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PEMEncryptor.java11
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PEMException.java34
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PEMKeyPair.java26
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PEMKeyPairParser.java9
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PEMParser.java510
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PEMUtilities.java64
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PEMWriter.java69
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PKCS8Generator.java87
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PasswordException.java10
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/PasswordFinder.java9
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaMiscPEMGenerator.java98
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaPEMKeyConverter.java115
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaPEMWriter.java68
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaPKCS8Generator.java18
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java141
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java221
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/jcajce/JcePEMDecryptorProviderBuilder.java54
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/jcajce/JcePEMEncryptorBuilder.java78
-rw-r--r--pkix/src/main/java/org/spongycastle/openssl/jcajce/PEMUtilities.java257
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/AsymmetricKeyUnwrapper.java19
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/AsymmetricKeyWrapper.java19
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/BufferingContentSigner.java70
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/ContentSigner.java27
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/ContentVerifier.java31
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/ContentVerifierProvider.java34
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java97
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/DefaultSecretKeySizeProvider.java69
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java224
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/DigestAlgorithmIdentifierFinder.java24
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/DigestCalculator.java36
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/DigestCalculatorProvider.java9
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/GenericKey.java41
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/InputDecryptor.java29
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/InputDecryptorProvider.java9
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/InputExpander.java29
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/InputExpanderProvider.java8
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/KeyUnwrapper.java11
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/KeyWrapper.java11
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/MacCalculator.java34
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/MacCalculatorProvider.java8
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/OperatorCreationException.java15
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/OperatorException.java24
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/OperatorStreamException.java21
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/OutputCompressor.java29
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/OutputEncryptor.java36
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/RawContentVerifier.java17
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/RuntimeOperatorException.java24
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/SecretKeySizeProvider.java17
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/SignatureAlgorithmIdentifierFinder.java15
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/SymmetricKeyUnwrapper.java19
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/SymmetricKeyWrapper.java19
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/AESUtil.java34
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java13
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcAESSymmetricKeyWrapper.java13
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcAsymmetricKeyUnwrapper.java51
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcAsymmetricKeyWrapper.java60
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcContentSignerBuilder.java82
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcContentVerifierProviderBuilder.java144
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcDSAContentSignerBuilder.java25
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java40
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcDefaultDigestProvider.java144
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcDigestCalculatorProvider.java82
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcDigestProvider.java11
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java22
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java32
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcRSAContentSignerBuilder.java24
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java39
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcSignerOutputStream.java47
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcSymmetricKeyUnwrapper.java49
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/BcSymmetricKeyWrapper.java51
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/CamelliaUtil.java36
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/OperatorUtils.java23
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/bc/SEEDUtil.java14
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java73
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/jcajce/JcaContentSignerBuilder.java160
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java312
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java114
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java133
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/jcajce/JceAsymmetricKeyWrapper.java157
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/jcajce/JceGenericKey.java33
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java65
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/jcajce/JceSymmetricKeyWrapper.java154
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/jcajce/OperatorHelper.java433
-rw-r--r--pkix/src/main/java/org/spongycastle/operator/jcajce/OperatorUtils.java25
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/MacDataGenerator.java49
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCS10CertificationRequest.java236
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCS10CertificationRequestBuilder.java156
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCS12MacCalculatorBuilder.java13
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCS12MacCalculatorBuilderProvider.java8
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCS12PfxPdu.java161
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCS12PfxPduBuilder.java179
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCS12SafeBag.java93
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCS12SafeBagBuilder.java76
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCS12SafeBagFactory.java58
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCS8EncryptedPrivateKeyInfo.java76
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCS8EncryptedPrivateKeyInfoBuilder.java54
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCSException.java27
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/PKCSIOException.java29
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS10CertificationRequest.java42
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java28
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java54
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java40
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java66
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java77
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/bc/PKCS12PBEUtils.java153
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java115
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java38
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS12SafeBagBuilder.java45
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS8EncryptedPrivateKeyInfoBuilder.java15
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilder.java122
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilderProvider.java108
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java177
-rw-r--r--pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java179
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/GenTimeAccuracy.java60
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TSPAlgorithms.java35
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TSPException.java28
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TSPIOException.java30
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TSPUtil.java209
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TSPValidationException.java34
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TimeStampRequest.java267
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TimeStampRequestGenerator.java163
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TimeStampResponse.java189
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TimeStampResponseGenerator.java353
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TimeStampToken.java393
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TimeStampTokenGenerator.java380
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/TimeStampTokenInfo.java121
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedData.java204
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedDataGenerator.java70
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java207
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java88
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/cms/ImprintDigestInvalidException.java21
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/cms/MetaDataUtil.java76
-rw-r--r--pkix/src/main/java/org/spongycastle/tsp/cms/TimeStampDataUtil.java256
-rw-r--r--pkix/src/main/java/org/spongycastle/voms/VOMSAttribute.java242
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/cert/cmp/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/cert/cmp/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/cert/crmf/jcajce/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/cert/crmf/jcajce/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/cert/crmf/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/cert/crmf/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/cert/jcajce/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/cert/jcajce/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/cert/ocsp/jcajce/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/cert/ocsp/jcajce/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/cert/ocsp/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/cert/ocsp/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/cert/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/cert/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/cert/selector/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/cert/selector/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/cms/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/cms/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/dvcs/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/dvcs/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/eac/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/eac/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/mozilla/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/mozilla/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/openssl/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/openssl/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/operator/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/operator/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/pkcs/jcajce/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/pkcs/jcajce/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/pkcs/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/pkcs/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/tsp/cms/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/tsp/cms/package.html)0
-rw-r--r--pkix/src/main/javadoc/org/spongycastle/tsp/package.html (renamed from pkix/src/main/javadoc/org/bouncycastle/tsp/package.html)0
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cert/cmp/GeneralPKIMessage.java82
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/CertificateRequestMessage.java309
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/FixedLengthMGF1Padder.java120
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java134
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/CRMFHelper.java485
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java120
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java140
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java69
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java149
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cert/path/CertPathValidationException.java24
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java34
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java57
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSAbsentContent.java49
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSProcessableByteArray.java55
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSProcessableFile.java80
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSTypedStream.java86
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/OriginatorInfoGenerator.java54
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/RecipientId.java31
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/SignerInfoGenerator.java291
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java671
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java54
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java24
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java166
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java184
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java212
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcePasswordRecipient.java107
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java81
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java113
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java156
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java240
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java164
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java311
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java127
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java159
-rw-r--r--pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/OperatorHelper.java477
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cert/cmp/GeneralPKIMessage.java82
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/CertificateRequestMessage.java309
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/FixedLengthMGF1Padder.java120
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java134
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/CRMFHelper.java485
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java120
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java140
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java69
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java149
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cert/path/CertPathValidationException.java24
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java34
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java57
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/CMSAbsentContent.java49
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/CMSProcessableByteArray.java55
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/CMSProcessableFile.java80
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/CMSTypedStream.java86
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/OriginatorInfoGenerator.java54
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/RecipientId.java31
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/SignerInfoGenerator.java291
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/EnvelopedDataHelper.java671
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcaSelectorConverter.java54
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java24
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java166
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JceKeyAgreeRecipient.java184
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java212
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcePasswordRecipient.java107
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java81
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/ZlibExpanderProvider.java113
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java156
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java240
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JcaContentSignerBuilder.java164
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java311
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java127
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JceSymmetricKeyWrapper.java159
-rw-r--r--pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/OperatorHelper.java477
-rw-r--r--pkix/src/main/jdk1.2/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java135
-rw-r--r--pkix/src/main/jdk1.2/org/bouncycastle/cert/jcajce/JcaAttrCertStore.java72
-rw-r--r--pkix/src/main/jdk1.2/org/bouncycastle/cms/bc/BcCMSContentEncryptorBuilder.java124
-rw-r--r--pkix/src/main/jdk1.2/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java161
-rw-r--r--pkix/src/main/jdk1.2/org/bouncycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java155
-rw-r--r--pkix/src/main/jdk1.2/org/spongycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java135
-rw-r--r--pkix/src/main/jdk1.2/org/spongycastle/cert/jcajce/JcaAttrCertStore.java72
-rw-r--r--pkix/src/main/jdk1.2/org/spongycastle/cms/bc/BcCMSContentEncryptorBuilder.java124
-rw-r--r--pkix/src/main/jdk1.2/org/spongycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java161
-rw-r--r--pkix/src/main/jdk1.2/org/spongycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java155
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java55
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java25
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java22
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java151
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX500NameUtil.java58
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509ExtensionUtils.java138
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v1CertificateBuilder.java31
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v2CRLBuilder.java15
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java54
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/ProviderCertHelper.java30
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java19
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java34
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java57
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java57
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java54
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JcaSignerId.java36
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java24
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientId.java32
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JceKeyTransRecipientId.java30
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/eac/jcajce/ProviderEACHelper.java23
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/eac/operator/jcajce/ProviderEACHelper.java23
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java44
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/operator/jcajce/OperatorHelper.java470
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java25
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedData.java204
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java207
-rw-r--r--pkix/src/main/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java90
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java55
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java25
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java22
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java151
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX500NameUtil.java58
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java138
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java31
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java15
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java54
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/ProviderCertHelper.java30
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java19
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java34
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java57
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java57
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSelectorConverter.java54
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSignerId.java36
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java24
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java32
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java30
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/eac/jcajce/ProviderEACHelper.java23
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java23
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java44
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/OperatorHelper.java470
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java25
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedData.java204
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java207
-rw-r--r--pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java90
-rw-r--r--pkix/src/main/jdk1.4/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java215
-rw-r--r--pkix/src/main/jdk1.4/org/bouncycastle/eac/jcajce/JcaPublicKeyConverter.java141
-rw-r--r--pkix/src/main/jdk1.4/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java44
-rw-r--r--pkix/src/main/jdk1.4/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java215
-rw-r--r--pkix/src/main/jdk1.4/org/spongycastle/eac/jcajce/JcaPublicKeyConverter.java141
-rw-r--r--pkix/src/main/jdk1.4/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java44
1062 files changed, 52142 insertions, 52142 deletions
diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/CertUtils.java b/pkix/src/main/j2me/org/bouncycastle/cert/CertUtils.java
deleted file mode 100644
index 0a4cb7c1..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/cert/CertUtils.java
+++ /dev/null
@@ -1,246 +0,0 @@
-package 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.ASN1GeneralizedTime;
-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)
- {
- 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());
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/X509AttributeCertificateHolder.java b/pkix/src/main/j2me/org/bouncycastle/cert/X509AttributeCertificateHolder.java
deleted file mode 100644
index 9f4f2378..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/cert/X509AttributeCertificateHolder.java
+++ /dev/null
@@ -1,366 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/X509CertificateHolder.java b/pkix/src/main/j2me/org/bouncycastle/cert/X509CertificateHolder.java
deleted file mode 100644
index 319c23a1..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/cert/X509CertificateHolder.java
+++ /dev/null
@@ -1,327 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/X509v1CertificateBuilder.java b/pkix/src/main/j2me/org/bouncycastle/cert/X509v1CertificateBuilder.java
deleted file mode 100644
index 3457e0c3..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/cert/X509v1CertificateBuilder.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package 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.ExtensionsGenerator;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.asn1.x509.Time;
-import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator;
-import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
-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)
- {
- this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo);
- }
-
- /**
- * Create a builder for a version 1 certificate.
- *
- * @param issuer the certificate issuer
- * @param serial the certificate serial number
- * @param notBefore the Time before which the certificate is not valid
- * @param notAfter the Time 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, Time notBefore, Time 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(notBefore);
- tbsGen.setEndDate(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());
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java b/pkix/src/main/j2me/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java
deleted file mode 100644
index 72efae91..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java
+++ /dev/null
@@ -1,138 +0,0 @@
-package 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;
-
- /**
- * Base constructor.
- *
- * @param holder holder certificate details
- * @param issuer issuer of this attribute certificate.
- * @param serialNumber serial number of this attribute certificate.
- * @param notBefore the date before which the certificate is not valid.
- * @param notAfter the date after which the certificate is not valid.
- */
- 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;
- }
-
- /**
- * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the
- * extension value.
- *
- * @param oid the OID defining the extension type.
- * @param isCritical true if the extension is critical, false otherwise.
- * @param encodedValue a byte array representing the encoding of the extension value.
- * @return this builder object.
- */
- public X509v2AttributeCertificateBuilder addExtension(
- ASN1ObjectIdentifier oid,
- boolean isCritical,
- byte[] encodedValue)
- throws CertIOException
- {
- extGenerator.addExtension(oid, isCritical, encodedValue);
-
- 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());
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/X509v2CRLBuilder.java b/pkix/src/main/j2me/org/bouncycastle/cert/X509v2CRLBuilder.java
deleted file mode 100644
index 6d54f0af..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/cert/X509v2CRLBuilder.java
+++ /dev/null
@@ -1,231 +0,0 @@
-package 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));
- }
-
- /**
- * Basic constructor.
- *
- * @param issuer the issuer this CRL is associated with.
- * @param thisUpdate the Time of this update.
- */
- public X509v2CRLBuilder(
- X500Name issuer,
- Time thisUpdate)
- {
- tbsGen = new V2TBSCertListGenerator();
- extGenerator = new ExtensionsGenerator();
-
- tbsGen.setIssuer(issuer);
- tbsGen.setThisUpdate(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)
- {
- return this.setNextUpdate(new Time(date));
- }
-
- /**
- * 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(
- Time date)
- {
- tbsGen.setNextUpdate(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;
- }
-
- /**
- * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the
- * extension value.
- *
- * @param oid the OID defining the extension type.
- * @param isCritical true if the extension is critical, false otherwise.
- * @param encodedValue a byte array representing the encoding of the extension value.
- * @return this builder object.
- */
- public X509v2CRLBuilder addExtension(
- ASN1ObjectIdentifier oid,
- boolean isCritical,
- byte[] encodedValue)
- throws CertIOException
- {
- extGenerator.addExtension(oid, isCritical, encodedValue);
-
- 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());
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/X509v3CertificateBuilder.java b/pkix/src/main/j2me/org/bouncycastle/cert/X509v3CertificateBuilder.java
deleted file mode 100644
index 48e08c19..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/cert/X509v3CertificateBuilder.java
+++ /dev/null
@@ -1,177 +0,0 @@
-package 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)
- {
- this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo);
- }
-
- /**
- * Create a builder for a version 3 certificate.
- *
- * @param issuer the certificate issuer
- * @param serial the certificate serial number
- * @param notBefore the Time before which the certificate is not valid
- * @param notAfter the Time 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, Time notBefore, Time notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
- {
- tbsGen = new V3TBSCertificateGenerator();
- tbsGen.setSerialNumber(new ASN1Integer(serial));
- tbsGen.setIssuer(issuer);
- tbsGen.setStartDate(notBefore);
- tbsGen.setEndDate(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) using a byte encoding of the
- * extension value.
- *
- * @param oid the OID defining the extension type.
- * @param isCritical true if the extension is critical, false otherwise.
- * @param encodedValue a byte array representing the encoding of the extension value.
- * @return this builder object.
- */
- public X509v3CertificateBuilder addExtension(
- ASN1ObjectIdentifier oid,
- boolean isCritical,
- byte[] encodedValue)
- throws CertIOException
- {
- extGenerator.addExtension(oid, isCritical, encodedValue);
-
- 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());
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/crmf/EncryptedValueParser.java b/pkix/src/main/j2me/org/bouncycastle/cert/crmf/EncryptedValueParser.java
deleted file mode 100644
index 86da4dda..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/cert/crmf/EncryptedValueParser.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/crmf/FixedLengthMGF1Padder.java b/pkix/src/main/j2me/org/bouncycastle/cert/crmf/FixedLengthMGF1Padder.java
deleted file mode 100644
index fe34b55d..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/cert/crmf/FixedLengthMGF1Padder.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/cms/CMSTypedStream.java b/pkix/src/main/j2me/org/bouncycastle/cms/CMSTypedStream.java
deleted file mode 100644
index c05c5952..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/cms/CMSTypedStream.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package 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;
- }
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/operator/bc/OperatorUtils.java b/pkix/src/main/j2me/org/bouncycastle/operator/bc/OperatorUtils.java
deleted file mode 100644
index 37aa1367..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/operator/bc/OperatorUtils.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package 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");
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/tsp/TimeStampToken.java b/pkix/src/main/j2me/org/bouncycastle/tsp/TimeStampToken.java
deleted file mode 100644
index 3cd7f0a9..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/tsp/TimeStampToken.java
+++ /dev/null
@@ -1,391 +0,0 @@
-package 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.
- * <p>
- * 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.
- * </p>
- * <p>
- * A successful call to validate means all the above are true.
- * </p>
- *
- * @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.
- * <p>
- * Note: this is a much weaker proof of correctness than calling validate().
- * </p>
- *
- * @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();
- }
- }
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/tsp/TimeStampTokenInfo.java b/pkix/src/main/j2me/org/bouncycastle/tsp/TimeStampTokenInfo.java
deleted file mode 100644
index 739794b0..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/tsp/TimeStampTokenInfo.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedData.java b/pkix/src/main/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedData.java
deleted file mode 100644
index 124c34c5..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedData.java
+++ /dev/null
@@ -1,201 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java b/pkix/src/main/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java
deleted file mode 100644
index 63988f79..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java
+++ /dev/null
@@ -1,204 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java b/pkix/src/main/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java
deleted file mode 100644
index d3d8be04..00000000
--- a/pkix/src/main/j2me/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/j2me/org/spongycastle/cert/CertUtils.java b/pkix/src/main/j2me/org/spongycastle/cert/CertUtils.java
new file mode 100644
index 00000000..c41d4b5e
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/cert/CertUtils.java
@@ -0,0 +1,246 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DEROutputStream;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.AttributeCertificate;
+import org.spongycastle.asn1.x509.AttributeCertificateInfo;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.CertificateList;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.TBSCertList;
+import org.spongycastle.asn1.x509.TBSCertificate;
+import org.spongycastle.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)
+ {
+ 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());
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/cert/X509AttributeCertificateHolder.java b/pkix/src/main/j2me/org/spongycastle/cert/X509AttributeCertificateHolder.java
new file mode 100644
index 00000000..e58587a7
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/cert/X509AttributeCertificateHolder.java
@@ -0,0 +1,366 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DEROutputStream;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.AttCertValidityPeriod;
+import org.spongycastle.asn1.x509.Attribute;
+import org.spongycastle.asn1.x509.AttributeCertificate;
+import org.spongycastle.asn1.x509.AttributeCertificateInfo;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/cert/X509CertificateHolder.java b/pkix/src/main/j2me/org/spongycastle/cert/X509CertificateHolder.java
new file mode 100644
index 00000000..0cf147f6
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/cert/X509CertificateHolder.java
@@ -0,0 +1,327 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DEROutputStream;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.TBSCertificate;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/cert/X509v1CertificateBuilder.java b/pkix/src/main/j2me/org/spongycastle/cert/X509v1CertificateBuilder.java
new file mode 100644
index 00000000..282ef9e4
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/cert/X509v1CertificateBuilder.java
@@ -0,0 +1,83 @@
+package org.spongycastle.cert;
+
+import java.math.BigInteger;
+import java.util.Date;
+
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.Time;
+import org.spongycastle.asn1.x509.V1TBSCertificateGenerator;
+import org.spongycastle.asn1.x509.V3TBSCertificateGenerator;
+import org.spongycastle.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)
+ {
+ this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo);
+ }
+
+ /**
+ * Create a builder for a version 1 certificate.
+ *
+ * @param issuer the certificate issuer
+ * @param serial the certificate serial number
+ * @param notBefore the Time before which the certificate is not valid
+ * @param notAfter the Time 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, Time notBefore, Time 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(notBefore);
+ tbsGen.setEndDate(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());
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/cert/X509v2AttributeCertificateBuilder.java b/pkix/src/main/j2me/org/spongycastle/cert/X509v2AttributeCertificateBuilder.java
new file mode 100644
index 00000000..fea5400f
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/cert/X509v2AttributeCertificateBuilder.java
@@ -0,0 +1,138 @@
+package org.spongycastle.cert;
+
+import java.math.BigInteger;
+import java.util.Date;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.x509.AttCertIssuer;
+import org.spongycastle.asn1.x509.Attribute;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.V2AttributeCertificateInfoGenerator;
+import org.spongycastle.operator.ContentSigner;
+
+/**
+ * class to produce an X.509 Version 2 AttributeCertificate.
+ */
+public class X509v2AttributeCertificateBuilder
+{
+ private V2AttributeCertificateInfoGenerator acInfoGen;
+ private ExtensionsGenerator extGenerator;
+
+ /**
+ * Base constructor.
+ *
+ * @param holder holder certificate details
+ * @param issuer issuer of this attribute certificate.
+ * @param serialNumber serial number of this attribute certificate.
+ * @param notBefore the date before which the certificate is not valid.
+ * @param notAfter the date after which the certificate is not valid.
+ */
+ 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;
+ }
+
+ /**
+ * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the
+ * extension value.
+ *
+ * @param oid the OID defining the extension type.
+ * @param isCritical true if the extension is critical, false otherwise.
+ * @param encodedValue a byte array representing the encoding of the extension value.
+ * @return this builder object.
+ */
+ public X509v2AttributeCertificateBuilder addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean isCritical,
+ byte[] encodedValue)
+ throws CertIOException
+ {
+ extGenerator.addExtension(oid, isCritical, encodedValue);
+
+ 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());
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/cert/X509v2CRLBuilder.java b/pkix/src/main/j2me/org/spongycastle/cert/X509v2CRLBuilder.java
new file mode 100644
index 00000000..d0e9e960
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/cert/X509v2CRLBuilder.java
@@ -0,0 +1,231 @@
+package org.spongycastle.cert;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.TBSCertList;
+import org.spongycastle.asn1.x509.Time;
+import org.spongycastle.asn1.x509.V2TBSCertListGenerator;
+import org.spongycastle.asn1.x509.X509Extensions;
+import org.spongycastle.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));
+ }
+
+ /**
+ * Basic constructor.
+ *
+ * @param issuer the issuer this CRL is associated with.
+ * @param thisUpdate the Time of this update.
+ */
+ public X509v2CRLBuilder(
+ X500Name issuer,
+ Time thisUpdate)
+ {
+ tbsGen = new V2TBSCertListGenerator();
+ extGenerator = new ExtensionsGenerator();
+
+ tbsGen.setIssuer(issuer);
+ tbsGen.setThisUpdate(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)
+ {
+ return this.setNextUpdate(new Time(date));
+ }
+
+ /**
+ * 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(
+ Time date)
+ {
+ tbsGen.setNextUpdate(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;
+ }
+
+ /**
+ * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the
+ * extension value.
+ *
+ * @param oid the OID defining the extension type.
+ * @param isCritical true if the extension is critical, false otherwise.
+ * @param encodedValue a byte array representing the encoding of the extension value.
+ * @return this builder object.
+ */
+ public X509v2CRLBuilder addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean isCritical,
+ byte[] encodedValue)
+ throws CertIOException
+ {
+ extGenerator.addExtension(oid, isCritical, encodedValue);
+
+ 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());
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/cert/X509v3CertificateBuilder.java b/pkix/src/main/j2me/org/spongycastle/cert/X509v3CertificateBuilder.java
new file mode 100644
index 00000000..f4f40ba0
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/cert/X509v3CertificateBuilder.java
@@ -0,0 +1,177 @@
+package org.spongycastle.cert;
+
+import java.math.BigInteger;
+import java.util.Date;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.Time;
+import org.spongycastle.asn1.x509.V3TBSCertificateGenerator;
+import org.spongycastle.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)
+ {
+ this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo);
+ }
+
+ /**
+ * Create a builder for a version 3 certificate.
+ *
+ * @param issuer the certificate issuer
+ * @param serial the certificate serial number
+ * @param notBefore the Time before which the certificate is not valid
+ * @param notAfter the Time 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, Time notBefore, Time notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
+ {
+ tbsGen = new V3TBSCertificateGenerator();
+ tbsGen.setSerialNumber(new ASN1Integer(serial));
+ tbsGen.setIssuer(issuer);
+ tbsGen.setStartDate(notBefore);
+ tbsGen.setEndDate(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) using a byte encoding of the
+ * extension value.
+ *
+ * @param oid the OID defining the extension type.
+ * @param isCritical true if the extension is critical, false otherwise.
+ * @param encodedValue a byte array representing the encoding of the extension value.
+ * @return this builder object.
+ */
+ public X509v3CertificateBuilder addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean isCritical,
+ byte[] encodedValue)
+ throws CertIOException
+ {
+ extGenerator.addExtension(oid, isCritical, encodedValue);
+
+ 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());
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/cert/crmf/EncryptedValueParser.java b/pkix/src/main/j2me/org/spongycastle/cert/crmf/EncryptedValueParser.java
new file mode 100644
index 00000000..0a0b1950
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/cert/crmf/EncryptedValueParser.java
@@ -0,0 +1,103 @@
+package org.spongycastle.cert.crmf;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.crmf.EncryptedValue;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.InputDecryptor;
+import org.spongycastle.util.Strings;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/cert/crmf/FixedLengthMGF1Padder.java b/pkix/src/main/j2me/org/spongycastle/cert/crmf/FixedLengthMGF1Padder.java
new file mode 100644
index 00000000..3335b7de
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/cert/crmf/FixedLengthMGF1Padder.java
@@ -0,0 +1,120 @@
+package org.spongycastle.cert.crmf;
+
+import java.security.SecureRandom;
+
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.digests.SHA1Digest;
+import org.spongycastle.crypto.generators.MGF1BytesGenerator;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/cms/CMSTypedStream.java b/pkix/src/main/j2me/org/spongycastle/cms/CMSTypedStream.java
new file mode 100644
index 00000000..5c79012b
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/cms/CMSTypedStream.java
@@ -0,0 +1,85 @@
+package org.spongycastle.cms;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.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;
+ }
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/operator/bc/OperatorUtils.java b/pkix/src/main/j2me/org/spongycastle/operator/bc/OperatorUtils.java
new file mode 100644
index 00000000..d0eae576
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/operator/bc/OperatorUtils.java
@@ -0,0 +1,16 @@
+package org.spongycastle.operator.bc;
+
+import org.spongycastle.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");
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/tsp/TimeStampToken.java b/pkix/src/main/j2me/org/spongycastle/tsp/TimeStampToken.java
new file mode 100644
index 00000000..d51a07fe
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/tsp/TimeStampToken.java
@@ -0,0 +1,391 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.cms.Attribute;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.IssuerAndSerialNumber;
+import org.spongycastle.asn1.ess.ESSCertID;
+import org.spongycastle.asn1.ess.ESSCertIDv2;
+import org.spongycastle.asn1.ess.SigningCertificate;
+import org.spongycastle.asn1.ess.SigningCertificateV2;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.tsp.TSTInfo;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.IssuerSerial;
+import org.spongycastle.asn1.x509.X509Name;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.CMSProcessable;
+import org.spongycastle.cms.CMSSignedData;
+import org.spongycastle.cms.SignerId;
+import org.spongycastle.cms.SignerInformation;
+import org.spongycastle.cms.SignerInformationVerifier;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.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.
+ * <p>
+ * 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.
+ * </p>
+ * <p>
+ * A successful call to validate means all the above are true.
+ * </p>
+ *
+ * @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.
+ * <p>
+ * Note: this is a much weaker proof of correctness than calling validate().
+ * </p>
+ *
+ * @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();
+ }
+ }
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/tsp/TimeStampTokenInfo.java b/pkix/src/main/j2me/org/spongycastle/tsp/TimeStampTokenInfo.java
new file mode 100644
index 00000000..0b3b3352
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/tsp/TimeStampTokenInfo.java
@@ -0,0 +1,112 @@
+package org.spongycastle.tsp;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Date;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.tsp.Accuracy;
+import org.spongycastle.asn1.tsp.TSTInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/tsp/cms/CMSTimeStampedData.java b/pkix/src/main/j2me/org/spongycastle/tsp/cms/CMSTimeStampedData.java
new file mode 100644
index 00000000..4d9c1653
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/tsp/cms/CMSTimeStampedData.java
@@ -0,0 +1,201 @@
+package org.spongycastle.tsp.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.Evidence;
+import org.spongycastle.asn1.cms.TimeStampAndCRL;
+import org.spongycastle.asn1.cms.TimeStampTokenEvidence;
+import org.spongycastle.asn1.cms.TimeStampedData;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java b/pkix/src/main/j2me/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java
new file mode 100644
index 00000000..f6439633
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java
@@ -0,0 +1,204 @@
+package org.spongycastle.tsp.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.BERTags;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfoParser;
+import org.spongycastle.asn1.cms.TimeStampedDataParser;
+import org.spongycastle.cms.CMSContentInfoParser;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.tsp.TimeStampToken;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/j2me/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java b/pkix/src/main/j2me/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java
new file mode 100644
index 00000000..ca6190de
--- /dev/null
+++ b/pkix/src/main/j2me/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java
@@ -0,0 +1,88 @@
+package org.spongycastle.tsp.cms;
+
+import org.spongycastle.asn1.ASN1Boolean;
+import org.spongycastle.asn1.DERBoolean;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.DERUTF8String;
+import org.spongycastle.asn1.cms.Attributes;
+import org.spongycastle.asn1.cms.MetaData;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java b/pkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java
deleted file mode 100644
index 074d3fc3..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/AttributeCertificateHolder.java
+++ /dev/null
@@ -1,357 +0,0 @@
-package 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.
- *
- * <pre>
- * 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
- * }
- * </pre>
- * <p>
- * <b>Note:</b> If objectDigestInfo comparisons are to be carried out the static
- * method setDigestCalculatorProvider <b>must</b> be called once to configure the class
- * to do the necessary calculations.
- * </p>
- */
-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.
- * <p>
- * <code>digestedObjectType</code> can be one of the following:
- * <ul>
- * <li>0 - publicKey - A hash of the public key of the holder must be
- * passed.
- * <li>1 - publicKeyCert - A hash of the public key certificate of the
- * holder must be passed.
- * <li>2 - otherObjectDigest - A hash of some other object type must be
- * passed. <code>otherObjectTypeID</code> must not be empty.
- * </ul>
- * <p>
- * 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
- * <code>digestedObjectType</code> is
- * <code>otherObjectDigest</code>.
- * @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.
- * <p>
- * <ul>
- * <li>0 - publicKey - A hash of the public key of the holder must be
- * passed.
- * <li>1 - publicKeyCert - A hash of the public key certificate of the
- * holder must be passed.
- * <li>2 - otherObjectDigest - A hash of some other object type must be
- * passed. <code>otherObjectTypeID</code> must not be empty.
- * </ul>
- *
- * @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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/AttributeCertificateIssuer.java b/pkix/src/main/java/org/bouncycastle/cert/AttributeCertificateIssuer.java
deleted file mode 100644
index b5084c94..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/AttributeCertificateIssuer.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/CertException.java b/pkix/src/main/java/org/bouncycastle/cert/CertException.java
deleted file mode 100644
index eb67a5d9..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/CertException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/CertIOException.java b/pkix/src/main/java/org/bouncycastle/cert/CertIOException.java
deleted file mode 100644
index 929d95e8..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/CertIOException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/CertRuntimeException.java b/pkix/src/main/java/org/bouncycastle/cert/CertRuntimeException.java
deleted file mode 100644
index 5384148a..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/CertRuntimeException.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package 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;
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/CertUtils.java b/pkix/src/main/java/org/bouncycastle/cert/CertUtils.java
deleted file mode 100644
index 9e2e488d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/CertUtils.java
+++ /dev/null
@@ -1,244 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java b/pkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java
deleted file mode 100644
index a34b3b34..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java
+++ /dev/null
@@ -1,366 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509CRLEntryHolder.java b/pkix/src/main/java/org/bouncycastle/cert/X509CRLEntryHolder.java
deleted file mode 100644
index a10f0143..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/X509CRLEntryHolder.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package 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.
- * <p>
- * 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.
- * </p>
- *
- * @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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java b/pkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
deleted file mode 100644
index b3723f38..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
+++ /dev/null
@@ -1,317 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java b/pkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
deleted file mode 100644
index 1081d937..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
+++ /dev/null
@@ -1,327 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509ContentVerifierProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/X509ContentVerifierProviderBuilder.java
deleted file mode 100644
index af3bd09c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/X509ContentVerifierProviderBuilder.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.bouncycastle.cert;
-
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.operator.ContentVerifierProvider;
-import org.bouncycastle.operator.OperatorCreationException;
-
-public interface X509ContentVerifierProviderBuilder
-{
- ContentVerifierProvider build(SubjectPublicKeyInfo validatingKeyInfo)
- throws OperatorCreationException;
-
- ContentVerifierProvider build(X509CertificateHolder validatingKeyInfo)
- throws OperatorCreationException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509ExtensionUtils.java b/pkix/src/main/java/org/bouncycastle/cert/X509ExtensionUtils.java
deleted file mode 100644
index aa371381..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/X509ExtensionUtils.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package org.bouncycastle.cert;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.math.BigInteger;
-
-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.
- * <p>
- * <b>Note:</b> This class is not thread safe!
- * </p>
- */
-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));
- }
-
- public AuthorityKeyIdentifier createAuthorityKeyIdentifier(SubjectPublicKeyInfo publicKeyInfo, GeneralNames generalNames, BigInteger serial)
- {
- return new AuthorityKeyIdentifier(calculateIdentifier(publicKeyInfo), generalNames, serial);
- }
-
- /**
- * Return a RFC 3280 type 1 key identifier. As in:
- * <pre>
- * (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).
- * </pre>
- * @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:
- * <pre>
- * (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.
- * </pre>
- * @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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509v1CertificateBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/X509v1CertificateBuilder.java
deleted file mode 100644
index 3652ba9e..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/X509v1CertificateBuilder.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package org.bouncycastle.cert;
-
-import java.math.BigInteger;
-import java.util.Date;
-import java.util.Locale;
-
-import org.bouncycastle.asn1.ASN1Integer;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.ExtensionsGenerator;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.asn1.x509.Time;
-import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator;
-import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
-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)
- {
- this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo);
- }
-
- /**
- * Create a builder for a version 1 certificate. You may need to use this constructor if the default locale
- * doesn't use a Gregorian calender so that the Time produced is compatible with other ASN.1 implementations.
- *
- * @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 dateLocale locale to be used for date interpretation.
- * @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, Locale dateLocale, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
- {
- this(issuer, serial, new Time(notBefore, dateLocale), new Time(notAfter, dateLocale), subject, publicKeyInfo);
- }
-
- /**
- * Create a builder for a version 1 certificate.
- *
- * @param issuer the certificate issuer
- * @param serial the certificate serial number
- * @param notBefore the Time before which the certificate is not valid
- * @param notAfter the Time 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, Time notBefore, Time 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(notBefore);
- tbsGen.setEndDate(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());
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java
deleted file mode 100644
index 4cd10a3f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java
+++ /dev/null
@@ -1,162 +0,0 @@
-package org.bouncycastle.cert;
-
-import java.math.BigInteger;
-import java.util.Date;
-import java.util.Locale;
-
-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;
-
- /**
- * Base constructor.
- *
- * @param holder holder certificate details
- * @param issuer issuer of this attribute certificate.
- * @param serialNumber serial number of this attribute certificate.
- * @param notBefore the date before which the certificate is not valid.
- * @param notAfter the date after which the certificate is not valid.
- */
- 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));
- }
-
- /**
- * Base constructor with locale for interpreting dates. You may need to use this constructor if the default locale
- * doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations.
- *
- * @param holder holder certificate details
- * @param issuer issuer of this attribute certificate.
- * @param serialNumber serial number of this attribute certificate.
- * @param notBefore the date before which the certificate is not valid.
- * @param notAfter the date after which the certificate is not valid.
- * @param dateLocale locale to be used for date interpretation.
- */
- public X509v2AttributeCertificateBuilder(AttributeCertificateHolder holder, AttributeCertificateIssuer issuer, BigInteger serialNumber, Date notBefore, Date notAfter, Locale dateLocale)
- {
- 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, dateLocale));
- acInfoGen.setEndDate(new ASN1GeneralizedTime(notAfter, dateLocale));
- }
-
- /**
- * 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;
- }
-
- /**
- * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the
- * extension value.
- *
- * @param oid the OID defining the extension type.
- * @param isCritical true if the extension is critical, false otherwise.
- * @param encodedValue a byte array representing the encoding of the extension value.
- * @return this builder object.
- */
- public X509v2AttributeCertificateBuilder addExtension(
- ASN1ObjectIdentifier oid,
- boolean isCritical,
- byte[] encodedValue)
- throws CertIOException
- {
- extGenerator.addExtension(oid, isCritical, encodedValue);
-
- 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509v2CRLBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/X509v2CRLBuilder.java
deleted file mode 100644
index 896f55be..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/X509v2CRLBuilder.java
+++ /dev/null
@@ -1,266 +0,0 @@
-package org.bouncycastle.cert;
-
-import java.math.BigInteger;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.Locale;
-
-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));
- }
-
- /**
- * Basic constructor with Locale. You may need to use this constructor if the default locale
- * doesn't use a Gregorian calender so that the Time produced is compatible with other ASN.1 implementations.
- *
- * @param issuer the issuer this CRL is associated with.
- * @param thisUpdate the date of this update.
- * @param dateLocale locale to be used for date interpretation.
- */
- public X509v2CRLBuilder(
- X500Name issuer,
- Date thisUpdate,
- Locale dateLocale)
- {
- tbsGen = new V2TBSCertListGenerator();
- extGenerator = new ExtensionsGenerator();
-
- tbsGen.setIssuer(issuer);
- tbsGen.setThisUpdate(new Time(thisUpdate, dateLocale));
- }
-
- /**
- * Basic constructor.
- *
- * @param issuer the issuer this CRL is associated with.
- * @param thisUpdate the Time of this update.
- */
- public X509v2CRLBuilder(
- X500Name issuer,
- Time thisUpdate)
- {
- tbsGen = new V2TBSCertListGenerator();
- extGenerator = new ExtensionsGenerator();
-
- tbsGen.setIssuer(issuer);
- tbsGen.setThisUpdate(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)
- {
- return this.setNextUpdate(new Time(date));
- }
-
- /**
- * Set the date by which the next CRL will become available.
- *
- * @param date date of next CRL update.
- * @param dateLocale locale to be used for date interpretation.
- * @return the current builder.
- */
- public X509v2CRLBuilder setNextUpdate(
- Date date,
- Locale dateLocale)
- {
- return this.setNextUpdate(new Time(date, dateLocale));
- }
-
- /**
- * 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(
- Time date)
- {
- tbsGen.setNextUpdate(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;
- }
-
- /**
- * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the
- * extension value.
- *
- * @param oid the OID defining the extension type.
- * @param isCritical true if the extension is critical, false otherwise.
- * @param encodedValue a byte array representing the encoding of the extension value.
- * @return this builder object.
- */
- public X509v2CRLBuilder addExtension(
- ASN1ObjectIdentifier oid,
- boolean isCritical,
- byte[] encodedValue)
- throws CertIOException
- {
- extGenerator.addExtension(oid, isCritical, encodedValue);
-
- 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java
deleted file mode 100644
index 22905b97..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/X509v3CertificateBuilder.java
+++ /dev/null
@@ -1,195 +0,0 @@
-package org.bouncycastle.cert;
-
-import java.math.BigInteger;
-import java.util.Date;
-import java.util.Locale;
-
-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)
- {
- this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo);
- }
-
- /**
- * Create a builder for a version 3 certificate. You may need to use this constructor if the default locale
- * doesn't use a Gregorian calender so that the Time produced is compatible with other ASN.1 implementations.
- *
- * @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 dateLocale locale to be used for date interpretation.
- * @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, Locale dateLocale, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
- {
- this(issuer, serial, new Time(notBefore, dateLocale), new Time(notAfter, dateLocale), subject, publicKeyInfo);
- }
-
- /**
- * Create a builder for a version 3 certificate.
- *
- * @param issuer the certificate issuer
- * @param serial the certificate serial number
- * @param notBefore the Time before which the certificate is not valid
- * @param notAfter the Time 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, Time notBefore, Time notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
- {
- tbsGen = new V3TBSCertificateGenerator();
- tbsGen.setSerialNumber(new ASN1Integer(serial));
- tbsGen.setIssuer(issuer);
- tbsGen.setStartDate(notBefore);
- tbsGen.setEndDate(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) using a byte encoding of the
- * extension value.
- *
- * @param oid the OID defining the extension type.
- * @param isCritical true if the extension is critical, false otherwise.
- * @param encodedValue a byte array representing the encoding of the extension value.
- * @return this builder object.
- */
- public X509v3CertificateBuilder addExtension(
- ASN1ObjectIdentifier oid,
- boolean isCritical,
- byte[] encodedValue)
- throws CertIOException
- {
- extGenerator.addExtension(oid, isCritical, encodedValue);
-
- 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());
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/bc/BcX509ExtensionUtils.java b/pkix/src/main/java/org/bouncycastle/cert/bc/BcX509ExtensionUtils.java
deleted file mode 100644
index c5a09536..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/bc/BcX509ExtensionUtils.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package 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:
- * <pre>
- * (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).
- * </pre>
- * @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;
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/bc/BcX509v1CertificateBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/bc/BcX509v1CertificateBuilder.java
deleted file mode 100644
index 5120030c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/bc/BcX509v1CertificateBuilder.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package 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));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/bc/BcX509v3CertificateBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/bc/BcX509v3CertificateBuilder.java
deleted file mode 100644
index e85fce1b..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/bc/BcX509v3CertificateBuilder.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package 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));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPException.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPException.java
deleted file mode 100644
index 2a1cc865..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package 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;
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPRuntimeException.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPRuntimeException.java
deleted file mode 100644
index 35b2d3fa..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPRuntimeException.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package 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;
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPUtil.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPUtil.java
deleted file mode 100644
index cc2ef04a..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/cmp/CMPUtil.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateConfirmationContent.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateConfirmationContent.java
deleted file mode 100644
index d1a2e643..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateConfirmationContent.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateConfirmationContentBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateConfirmationContentBuilder.java
deleted file mode 100644
index 578ae148..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateConfirmationContentBuilder.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package 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);
- }
-
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateStatus.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateStatus.java
deleted file mode 100644
index 50df835f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/cmp/CertificateStatus.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/GeneralPKIMessage.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/GeneralPKIMessage.java
deleted file mode 100644
index a928623f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/cmp/GeneralPKIMessage.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessage.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessage.java
deleted file mode 100644
index 2749d908..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessage.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessageBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessageBuilder.java
deleted file mode 100644
index 29191567..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/cmp/ProtectedPKIMessageBuilder.java
+++ /dev/null
@@ -1,306 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/RevocationDetails.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/RevocationDetails.java
deleted file mode 100644
index f382c69c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/cmp/RevocationDetails.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/cmp/RevocationDetailsBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/cmp/RevocationDetailsBuilder.java
deleted file mode 100644
index e662d28e..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/cmp/RevocationDetailsBuilder.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/AuthenticatorControl.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/AuthenticatorControl.java
deleted file mode 100644
index 3cb7f470..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/AuthenticatorControl.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/CRMFException.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/CRMFException.java
deleted file mode 100644
index 8ea6ecdc..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/CRMFException.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package 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;
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/CRMFRuntimeException.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/CRMFRuntimeException.java
deleted file mode 100644
index 89d6a537..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/CRMFRuntimeException.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package 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;
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/CRMFUtil.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/CRMFUtil.java
deleted file mode 100644
index f314a950..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/CRMFUtil.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessage.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessage.java
deleted file mode 100644
index e532c2b5..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessage.java
+++ /dev/null
@@ -1,309 +0,0 @@
-package 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();
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessageBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessageBuilder.java
deleted file mode 100644
index aa482357..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/CertificateRequestMessageBuilder.java
+++ /dev/null
@@ -1,279 +0,0 @@
-package org.bouncycastle.cert.crmf;
-
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Date;
-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.OptionalValidity;
-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.asn1.x509.Time;
-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;
- }
-
- /**
- * Request a validity period for the certificate. Either, but not both, of the date parameters may be null.
- *
- * @param notBeforeDate not before date for certificate requested.
- * @param notAfterDate not after date for the certificate requested.
- *
- * @return the current builder.
- */
- public CertificateRequestMessageBuilder setValidity(Date notBeforeDate, Date notAfterDate)
- {
- templateBuilder.setValidity(new OptionalValidity(createTime(notBeforeDate), createTime(notAfterDate)));
-
- return this;
- }
-
- private Time createTime(Date date)
- {
- if (date != null)
- {
- return new Time(date);
- }
-
- return null;
- }
-
- 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)));
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/Control.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/Control.java
deleted file mode 100644
index f86f8a0f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/Control.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package 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();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValueBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValueBuilder.java
deleted file mode 100644
index 55187b5b..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValueBuilder.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValuePadder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValuePadder.java
deleted file mode 100644
index 41ca8668..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValuePadder.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package 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);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValueParser.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValueParser.java
deleted file mode 100644
index 6c0aa877..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/EncryptedValueParser.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKIArchiveControl.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/PKIArchiveControl.java
deleted file mode 100644
index 7bc99579..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKIArchiveControl.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKIArchiveControlBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/PKIArchiveControlBuilder.java
deleted file mode 100644
index 9edf75c7..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKIArchiveControlBuilder.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package 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)));
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACBuilder.java
deleted file mode 100644
index abbdaed8..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACBuilder.java
+++ /dev/null
@@ -1,199 +0,0 @@
-package 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);
- }
- }
- };
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueGenerator.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueGenerator.java
deleted file mode 100644
index 2457687d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueGenerator.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueVerifier.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueVerifier.java
deleted file mode 100644
index 1d8c3692..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValueVerifier.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package 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());
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValuesCalculator.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValuesCalculator.java
deleted file mode 100644
index 2813b6c0..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/PKMACValuesCalculator.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package 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;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java
deleted file mode 100644
index 72979801..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/RegTokenControl.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/RegTokenControl.java
deleted file mode 100644
index 81af172c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/RegTokenControl.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/ValueDecryptorGenerator.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/ValueDecryptorGenerator.java
deleted file mode 100644
index 7125f56f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/ValueDecryptorGenerator.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package 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;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java
deleted file mode 100644
index 9fa53d62..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package org.bouncycastle.cert.crmf.bc;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.cert.crmf.EncryptedValuePadder;
-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 BcFixedLengthMGF1Padder
- 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 BcFixedLengthMGF1Padder(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 BcFixedLengthMGF1Padder(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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/CRMFHelper.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/CRMFHelper.java
deleted file mode 100644
index 4878615b..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/CRMFHelper.java
+++ /dev/null
@@ -1,450 +0,0 @@
-package 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.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceUtils;
-
-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
- {
- JcaJceUtils.loadParameters(params, sParams);
- }
- 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 = JcaJceUtils.extractParameters(params);
- }
- 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java
deleted file mode 100644
index 7f33d17a..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java
deleted file mode 100644
index 63eea67f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaEncryptedValueBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaEncryptedValueBuilder.java
deleted file mode 100644
index 91d22a0e..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaEncryptedValueBuilder.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package 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));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java
deleted file mode 100644
index ab892416..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java
deleted file mode 100644
index ff1158e9..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- };
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java
deleted file mode 100644
index 701d36ea..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java b/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java
deleted file mode 100644
index 30423db5..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/CertHelper.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/CertHelper.java
deleted file mode 100644
index dee69967..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/CertHelper.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package 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;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/DefaultCertHelper.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/DefaultCertHelper.java
deleted file mode 100644
index 3966b493..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/DefaultCertHelper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaAttrCertStore.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaAttrCertStore.java
deleted file mode 100644
index b857d966..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaAttrCertStore.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package 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.
- * <p>
- * The class will convert X509AttributeCertificate objects into X509AttributeCertificateHolder objects.
- * </p>
- */
-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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaAttributeCertificateIssuer.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaAttributeCertificateIssuer.java
deleted file mode 100644
index f5bfa68d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaAttributeCertificateIssuer.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.bouncycastle.cert.jcajce;
-
-import java.security.cert.X509Certificate;
-
-import javax.security.auth.x500.X500Principal;
-
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.cert.AttributeCertificateIssuer;
-
-public class JcaAttributeCertificateIssuer
- extends AttributeCertificateIssuer
-{
- /**
- * Base constructor.
- *
- * @param issuerCert certificate for the issuer of the attribute certificate.
- */
- public JcaAttributeCertificateIssuer(X509Certificate issuerCert)
- {
- this(issuerCert.getIssuerX500Principal());
- }
-
- /**
- * Base constructor.
- *
- * @param issuerDN X.500 DN for the issuer of the attribute certificate.
- */
- public JcaAttributeCertificateIssuer(X500Principal issuerDN)
- {
- super(X500Name.getInstance(issuerDN.getEncoded()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaCRLStore.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaCRLStore.java
deleted file mode 100644
index 2e8209e9..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaCRLStore.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package 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.
- * <p>
- * The class will convert X509CRL objects into X509CRLHolder objects.
- * </p>
- */
-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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaCertStore.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaCertStore.java
deleted file mode 100644
index e7433642..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaCertStore.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package 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.
- * <p>
- * The class will convert X509Certificate objects into X509CertificateHolder objects.
- * </p>
- */
-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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java
deleted file mode 100644
index 3051a455..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java
+++ /dev/null
@@ -1,148 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX500NameUtil.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX500NameUtil.java
deleted file mode 100644
index 2b64340e..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX500NameUtil.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509AttributeCertificateHolder.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509AttributeCertificateHolder.java
deleted file mode 100644
index 1ceafce0..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509AttributeCertificateHolder.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CRLConverter.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CRLConverter.java
deleted file mode 100644
index ae06334f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CRLConverter.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package 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;
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CRLHolder.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CRLHolder.java
deleted file mode 100644
index 43665c02..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CRLHolder.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CertificateConverter.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CertificateConverter.java
deleted file mode 100644
index 39e63aa4..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CertificateConverter.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package 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;
- }
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CertificateHolder.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CertificateHolder.java
deleted file mode 100644
index d0611843..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509CertificateHolder.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509ContentVerifierProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509ContentVerifierProviderBuilder.java
deleted file mode 100644
index 5f4c530f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509ContentVerifierProviderBuilder.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.bouncycastle.cert.jcajce;
-
-import java.security.Provider;
-import java.security.cert.CertificateException;
-
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.X509ContentVerifierProviderBuilder;
-import org.bouncycastle.operator.ContentVerifierProvider;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
-
-public class JcaX509ContentVerifierProviderBuilder
- implements X509ContentVerifierProviderBuilder
-{
- private JcaContentVerifierProviderBuilder builder = new JcaContentVerifierProviderBuilder();
-
- public JcaX509ContentVerifierProviderBuilder setProvider(Provider provider)
- {
- this.builder.setProvider(provider);
-
- return this;
- }
-
- public JcaX509ContentVerifierProviderBuilder setProvider(String providerName)
- {
- this.builder.setProvider(providerName);
-
- return this;
- }
-
- public ContentVerifierProvider build(SubjectPublicKeyInfo validatingKeyInfo)
- throws OperatorCreationException
- {
- return builder.build(validatingKeyInfo);
- }
-
- public ContentVerifierProvider build(X509CertificateHolder validatingKeyInfo)
- throws OperatorCreationException
- {
- try
- {
- return builder.build(validatingKeyInfo);
- }
- catch (CertificateException e)
- {
- throw new OperatorCreationException("Unable to process certificate: " + e.getMessage(), e);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509ExtensionUtils.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509ExtensionUtils.java
deleted file mode 100644
index 162c94f1..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509ExtensionUtils.java
+++ /dev/null
@@ -1,145 +0,0 @@
-package org.bouncycastle.cert.jcajce;
-
-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.PublicKey;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-
-import javax.security.auth.x500.X500Principal;
-
-import org.bouncycastle.asn1.ASN1OctetString;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
-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.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()));
- }
-
- public AuthorityKeyIdentifier createAuthorityKeyIdentifier(PublicKey pubKey, X500Principal name, BigInteger serial)
- {
- return super.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), new GeneralNames(new GeneralName(X500Name.getInstance(name.getEncoded()))), serial);
- }
-
- public AuthorityKeyIdentifier createAuthorityKeyIdentifier(PublicKey pubKey, GeneralNames generalNames, BigInteger serial)
- {
- return super.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), generalNames, serial);
- }
-
- /**
- * Return a RFC 3280 type 1 key identifier. As in:
- * <pre>
- * (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).
- * </pre>
- * @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:
- * <pre>
- * (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.
- * </pre>
- * @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;
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509v1CertificateBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509v1CertificateBuilder.java
deleted file mode 100644
index e453fc71..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509v1CertificateBuilder.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509v2CRLBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509v2CRLBuilder.java
deleted file mode 100644
index 43c39184..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509v2CRLBuilder.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java
deleted file mode 100644
index ae33009c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package 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.asn1.x509.Time;
-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 a PublicKey.
- *
- * @param issuer X500Name representing the issuer of this certificate.
- * @param serial the serial number for the certificate.
- * @param notBefore Time before which the certificate is not valid.
- * @param notAfter Time 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, Time notBefore, Time 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/NamedCertHelper.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/NamedCertHelper.java
deleted file mode 100644
index 5cd2feb4..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/NamedCertHelper.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package 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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/jcajce/ProviderCertHelper.java b/pkix/src/main/java/org/bouncycastle/cert/jcajce/ProviderCertHelper.java
deleted file mode 100644
index 15c9e729..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/jcajce/ProviderCertHelper.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package 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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPResp.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPResp.java
deleted file mode 100644
index 82b9f232..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPResp.java
+++ /dev/null
@@ -1,212 +0,0 @@
-package 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;
-
-/**
- * <pre>
- * BasicOCSPResponse ::= SEQUENCE {
- * tbsResponseData ResponseData,
- * signatureAlgorithm AlgorithmIdentifier,
- * signature BIT STRING,
- * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
- * </pre>
- */
-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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPRespBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPRespBuilder.java
deleted file mode 100644
index d06dcfca..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/BasicOCSPRespBuilder.java
+++ /dev/null
@@ -1,264 +0,0 @@
-package 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;
- ASN1GeneralizedTime thisUpdate;
- ASN1GeneralizedTime 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));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/CertificateID.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/CertificateID.java
deleted file mode 100644
index c6b09ad8..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/CertificateID.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/CertificateStatus.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/CertificateStatus.java
deleted file mode 100644
index 3aa117df..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/CertificateStatus.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package org.bouncycastle.cert.ocsp;
-
-public interface CertificateStatus
-{
- public static final CertificateStatus GOOD = null;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPException.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPException.java
deleted file mode 100644
index 6489788c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java
deleted file mode 100644
index 2706c401..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReq.java
+++ /dev/null
@@ -1,259 +0,0 @@
-package 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;
-
-/**
- * <pre>
- * 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 }
- * </pre>
- */
-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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java
deleted file mode 100644
index e7e8e0f5..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java
+++ /dev/null
@@ -1,199 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java
deleted file mode 100644
index ed3918ac..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPResp.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPRespBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPRespBuilder.java
deleted file mode 100644
index c372ebff..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPRespBuilder.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package 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");
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPUtils.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPUtils.java
deleted file mode 100644
index a84f409c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPUtils.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/Req.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/Req.java
deleted file mode 100644
index 6df083c5..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/Req.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/RespData.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/RespData.java
deleted file mode 100644
index 6960fa8f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/RespData.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/RespID.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/RespID.java
deleted file mode 100644
index 4322ab5b..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/RespID.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/RevokedStatus.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/RevokedStatus.java
deleted file mode 100644
index d349f076..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/RevokedStatus.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/SingleResp.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/SingleResp.java
deleted file mode 100644
index ece7ea2e..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/SingleResp.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/UnknownStatus.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/UnknownStatus.java
deleted file mode 100644
index 8d60e2ba..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/UnknownStatus.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.bouncycastle.cert.ocsp;
-
-/**
- * wrapper for the UnknownInfo object
- */
-public class UnknownStatus
- implements CertificateStatus
-{
- public UnknownStatus()
- {
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java
deleted file mode 100644
index 94bf52f0..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaCertificateID.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaCertificateID.java
deleted file mode 100644
index 446b38bb..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaCertificateID.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java b/pkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java
deleted file mode 100644
index 8bc9edbd..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/CertPath.java b/pkix/src/main/java/org/bouncycastle/cert/path/CertPath.java
deleted file mode 100644
index f91b3a81..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/CertPath.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.bouncycastle.cert.path;
-
-import org.bouncycastle.cert.X509CertificateHolder;
-
-public class CertPath
-{
- private final X509CertificateHolder[] certificates;
-
- public CertPath(X509CertificateHolder[] certificates)
- {
- this.certificates = copyArray(certificates);
- }
-
- public X509CertificateHolder[] getCertificates()
- {
- return copyArray(certificates);
- }
-
- public CertPathValidationResult validate(CertPathValidation[] ruleSet)
- {
- CertPathValidationContext context = new CertPathValidationContext(CertPathUtils.getCriticalExtensionsOIDs(certificates));
-
- for (int i = 0; i != ruleSet.length; i++)
- {
- for (int j = certificates.length - 1; j >= 0; j--)
- {
- try
- {
- context.setIsEndEntity(j == 0);
- ruleSet[i].validate(context, certificates[j]);
- }
- catch (CertPathValidationException e)
- { // TODO: introduce object to hold (i and e)
- return new CertPathValidationResult(context, j, i, e);
- }
- }
- }
-
- return new CertPathValidationResult(context);
- }
-
- public CertPathValidationResult evaluate(CertPathValidation[] ruleSet)
- {
- CertPathValidationContext context = new CertPathValidationContext(CertPathUtils.getCriticalExtensionsOIDs(certificates));
-
- CertPathValidationResultBuilder builder = new CertPathValidationResultBuilder();
-
- for (int i = 0; i != ruleSet.length; i++)
- {
- for (int j = certificates.length - 1; j >= 0; j--)
- {
- try
- {
- context.setIsEndEntity(j == 0);
- ruleSet[i].validate(context, certificates[j]);
- }
- catch (CertPathValidationException e)
- {
- builder.addException(e);
- }
- }
- }
-
- return builder.build();
- }
-
- private X509CertificateHolder[] copyArray(X509CertificateHolder[] array)
- {
- X509CertificateHolder[] rv = new X509CertificateHolder[array.length];
-
- System.arraycopy(array, 0, rv, 0, rv.length);
-
- return rv;
- }
-
- public int length()
- {
- return certificates.length;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathUtils.java b/pkix/src/main/java/org/bouncycastle/cert/path/CertPathUtils.java
deleted file mode 100644
index 4811a3d8..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathUtils.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.bouncycastle.cert.path;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.bouncycastle.cert.X509CertificateHolder;
-
-class CertPathUtils
-{
- static Set getCriticalExtensionsOIDs(X509CertificateHolder[] certificates)
- {
- Set criticalExtensions = new HashSet();
-
- for (int i = 0; i != certificates.length; i++)
- {
- criticalExtensions.addAll(certificates[i].getCriticalExtensionOIDs());
- }
-
- return criticalExtensions;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidation.java b/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidation.java
deleted file mode 100644
index 2704fe64..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidation.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.bouncycastle.cert.path;
-
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.util.Memoable;
-
-public interface CertPathValidation
- extends Memoable
-{
- public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
- throws CertPathValidationException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationContext.java b/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationContext.java
deleted file mode 100644
index 6a4b0ec2..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationContext.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.bouncycastle.cert.path;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.util.Memoable;
-
-public class CertPathValidationContext
- implements Memoable
-{
- private Set criticalExtensions;
-
- private Set handledExtensions = new HashSet();
- private boolean endEntity;
- private int index;
-
- public CertPathValidationContext(Set criticalExtensionsOIDs)
- {
- this.criticalExtensions = criticalExtensionsOIDs;
- }
-
- public void addHandledExtension(ASN1ObjectIdentifier extensionIdentifier)
- {
- this.handledExtensions.add(extensionIdentifier);
- }
-
- public void setIsEndEntity(boolean isEndEntity)
- {
- this.endEntity = isEndEntity;
- }
-
- public Set getUnhandledCriticalExtensionOIDs()
- {
- Set rv = new HashSet(criticalExtensions);
-
- rv.removeAll(handledExtensions);
-
- return rv;
- }
-
- /**
- * Returns true if the current certificate is the end-entity certificate.
- *
- * @return if current cert end-entity, false otherwise.
- */
- public boolean isEndEntity()
- {
- return endEntity;
- }
-
- public Memoable copy()
- {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void reset(Memoable other)
- {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationException.java b/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationException.java
deleted file mode 100644
index 958f2d0c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.bouncycastle.cert.path;
-
-public class CertPathValidationException
- extends Exception
-{
- private final Exception cause;
-
- public CertPathValidationException(String msg)
- {
- this(msg, null);
- }
-
- public CertPathValidationException(String msg, Exception cause)
- {
- super(msg);
-
- this.cause = cause;
- }
-
- public Throwable getCause()
- {
- return cause;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationResult.java b/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationResult.java
deleted file mode 100644
index facefb45..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationResult.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.bouncycastle.cert.path;
-
-import java.util.Collections;
-import java.util.Set;
-
-public class CertPathValidationResult
-{
- private final boolean isValid;
- private final CertPathValidationException cause;
- private final Set unhandledCriticalExtensionOIDs;
-
- private int[] certIndexes;
-
- public CertPathValidationResult(CertPathValidationContext context)
- {
- this.unhandledCriticalExtensionOIDs = Collections.unmodifiableSet(context.getUnhandledCriticalExtensionOIDs());
- this.isValid = this.unhandledCriticalExtensionOIDs.isEmpty();
- cause = null;
- }
-
- public CertPathValidationResult(CertPathValidationContext context, int certIndex, int ruleIndex, CertPathValidationException cause)
- {
- this.unhandledCriticalExtensionOIDs = Collections.unmodifiableSet(context.getUnhandledCriticalExtensionOIDs());
- this.isValid = false;
- this.cause = cause;
- }
-
- public CertPathValidationResult(CertPathValidationContext context, int[] certIndexes, int[] ruleIndexes, CertPathValidationException[] cause)
- {
- // TODO
- this.unhandledCriticalExtensionOIDs = Collections.unmodifiableSet(context.getUnhandledCriticalExtensionOIDs());
- this.isValid = false;
- this.cause = cause[0];
- this.certIndexes = certIndexes;
- }
-
- public boolean isValid()
- {
- return isValid;
- }
-
- public Exception getCause()
- {
- if (cause != null)
- {
- return cause;
- }
-
- if (!unhandledCriticalExtensionOIDs.isEmpty())
- {
- return new CertPathValidationException("Unhandled Critical Extensions");
- }
-
- return null;
- }
-
- public Set getUnhandledCriticalExtensionOIDs()
- {
- return unhandledCriticalExtensionOIDs;
- }
-
- public boolean isDetailed()
- {
- return this.certIndexes != null;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationResultBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationResultBuilder.java
deleted file mode 100644
index 9e813396..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/CertPathValidationResultBuilder.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.bouncycastle.cert.path;
-
-class CertPathValidationResultBuilder
-{
- public CertPathValidationResult build()
- {
- return new CertPathValidationResult(null, 0, 0, null);
- }
-
- public void addException(CertPathValidationException exception)
- {
- //To change body of created methods use File | Settings | File Templates.
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/validations/BasicConstraintsValidation.java b/pkix/src/main/java/org/bouncycastle/cert/path/validations/BasicConstraintsValidation.java
deleted file mode 100644
index db4f8527..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/validations/BasicConstraintsValidation.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package org.bouncycastle.cert.path.validations;
-
-import java.math.BigInteger;
-
-import org.bouncycastle.asn1.x509.BasicConstraints;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.path.CertPathValidation;
-import org.bouncycastle.cert.path.CertPathValidationContext;
-import org.bouncycastle.cert.path.CertPathValidationException;
-import org.bouncycastle.util.Memoable;
-
-public class BasicConstraintsValidation
- implements CertPathValidation
-{
- private boolean isMandatory;
- private BasicConstraints bc;
- private int maxPathLength;
-
- public BasicConstraintsValidation()
- {
- this(true);
- }
-
- public BasicConstraintsValidation(boolean isMandatory)
- {
- this.isMandatory = isMandatory;
- }
-
- public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
- throws CertPathValidationException
- {
- if (maxPathLength < 0)
- {
- throw new CertPathValidationException("BasicConstraints path length exceeded");
- }
-
- context.addHandledExtension(Extension.basicConstraints);
-
- BasicConstraints certBC = BasicConstraints.fromExtensions(certificate.getExtensions());
-
- if (certBC != null)
- {
- if (bc != null)
- {
- if (certBC.isCA())
- {
- BigInteger pathLengthConstraint = certBC.getPathLenConstraint();
-
- if (pathLengthConstraint != null)
- {
- int plc = pathLengthConstraint.intValue();
-
- if (plc < maxPathLength)
- {
- maxPathLength = plc;
- bc = certBC;
- }
- }
- }
- }
- else
- {
- bc = certBC;
- if (certBC.isCA())
- {
- maxPathLength = certBC.getPathLenConstraint().intValue();
- }
- }
- }
- else
- {
- if (bc != null)
- {
- maxPathLength--;
- }
- }
-
- if (isMandatory && bc == null)
- {
- throw new CertPathValidationException("BasicConstraints not present in path");
- }
- }
-
- public Memoable copy()
- {
- BasicConstraintsValidation v = new BasicConstraintsValidation(isMandatory);
-
- v.bc = this.bc;
- v.maxPathLength = this.maxPathLength;
-
- return v;
- }
-
- public void reset(Memoable other)
- {
- BasicConstraintsValidation v = (BasicConstraintsValidation)other;
-
- this.isMandatory = v.isMandatory;
- this.bc = v.bc;
- this.maxPathLength = v.maxPathLength;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/validations/CRLValidation.java b/pkix/src/main/java/org/bouncycastle/cert/path/validations/CRLValidation.java
deleted file mode 100644
index c44b7c0d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/validations/CRLValidation.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.bouncycastle.cert.path.validations;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.cert.X509CRLHolder;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.path.CertPathValidation;
-import org.bouncycastle.cert.path.CertPathValidationContext;
-import org.bouncycastle.cert.path.CertPathValidationException;
-import org.bouncycastle.util.Memoable;
-import org.bouncycastle.util.Selector;
-import org.bouncycastle.util.Store;
-
-public class CRLValidation
- implements CertPathValidation
-{
- private Store crls;
- private X500Name workingIssuerName;
-
- public CRLValidation(X500Name trustAnchorName, Store crls)
- {
- this.workingIssuerName = trustAnchorName;
- this.crls = crls;
- }
-
- public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
- throws CertPathValidationException
- {
- // TODO: add handling of delta CRLs
- Collection matches = crls.getMatches(new Selector()
- {
- public boolean match(Object obj)
- {
- X509CRLHolder crl = (X509CRLHolder)obj;
-
- return (crl.getIssuer().equals(workingIssuerName));
- }
-
- public Object clone()
- {
- return this;
- }
- });
-
- if (matches.isEmpty())
- {
- throw new CertPathValidationException("CRL for " + workingIssuerName + " not found");
- }
-
- for (Iterator it = matches.iterator(); it.hasNext();)
- {
- X509CRLHolder crl = (X509CRLHolder)it.next();
-
- // TODO: not quite right!
- if (crl.getRevokedCertificate(certificate.getSerialNumber()) != null)
- {
- throw new CertPathValidationException("Certificate revoked");
- }
- }
-
- this.workingIssuerName = certificate.getSubject();
- }
-
- public Memoable copy()
- {
- return new CRLValidation(workingIssuerName, crls);
- }
-
- public void reset(Memoable other)
- {
- CRLValidation v = (CRLValidation)other;
-
- this.workingIssuerName = v.workingIssuerName;
- this.crls = v.crls;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/validations/CertificatePoliciesValidation.java b/pkix/src/main/java/org/bouncycastle/cert/path/validations/CertificatePoliciesValidation.java
deleted file mode 100644
index ebaf9897..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/validations/CertificatePoliciesValidation.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package org.bouncycastle.cert.path.validations;
-
-import java.math.BigInteger;
-
-import org.bouncycastle.asn1.ASN1Integer;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.PolicyConstraints;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.path.CertPathValidation;
-import org.bouncycastle.cert.path.CertPathValidationContext;
-import org.bouncycastle.cert.path.CertPathValidationException;
-import org.bouncycastle.util.Memoable;
-
-public class CertificatePoliciesValidation
- implements CertPathValidation
-{
- private int explicitPolicy;
- private int policyMapping;
- private int inhibitAnyPolicy;
-
- CertificatePoliciesValidation(int pathLength)
- {
- this(pathLength, false, false, false);
- }
-
- CertificatePoliciesValidation(int pathLength, boolean isExplicitPolicyRequired, boolean isAnyPolicyInhibited, boolean isPolicyMappingInhibited)
- {
- //
- // (d)
- //
-
- if (isExplicitPolicyRequired)
- {
- explicitPolicy = 0;
- }
- else
- {
- explicitPolicy = pathLength + 1;
- }
-
- //
- // (e)
- //
- if (isAnyPolicyInhibited)
- {
- inhibitAnyPolicy = 0;
- }
- else
- {
- inhibitAnyPolicy = pathLength + 1;
- }
-
- //
- // (f)
- //
- if (isPolicyMappingInhibited)
- {
- policyMapping = 0;
- }
- else
- {
- policyMapping = pathLength + 1;
- }
- }
-
- public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
- throws CertPathValidationException
- {
- context.addHandledExtension(Extension.policyConstraints);
- context.addHandledExtension(Extension.inhibitAnyPolicy);
-
- if (!context.isEndEntity())
- {
- if (!ValidationUtils.isSelfIssued(certificate))
- {
- //
- // H (1), (2), (3)
- //
- explicitPolicy = countDown(explicitPolicy);
- policyMapping = countDown(policyMapping);
- inhibitAnyPolicy = countDown(inhibitAnyPolicy);
-
- //
- // I (1), (2)
- //
- PolicyConstraints policyConstraints = PolicyConstraints.fromExtensions(certificate.getExtensions());
-
- if (policyConstraints != null)
- {
- BigInteger requireExplicitPolicyMapping = policyConstraints.getRequireExplicitPolicyMapping();
- if (requireExplicitPolicyMapping != null)
- {
- if (requireExplicitPolicyMapping.intValue() < explicitPolicy)
- {
- explicitPolicy = requireExplicitPolicyMapping.intValue();
- }
- }
-
- BigInteger inhibitPolicyMapping = policyConstraints.getInhibitPolicyMapping();
- if (inhibitPolicyMapping != null)
- {
- if (inhibitPolicyMapping.intValue() < policyMapping)
- {
- policyMapping = inhibitPolicyMapping.intValue();
- }
- }
- }
-
- //
- // J
- //
- Extension ext = certificate.getExtension(Extension.inhibitAnyPolicy);
-
- if (ext != null)
- {
- int extValue = ASN1Integer.getInstance(ext.getParsedValue()).getValue().intValue();
-
- if (extValue < inhibitAnyPolicy)
- {
- inhibitAnyPolicy = extValue;
- }
- }
- }
- }
- }
-
- private int countDown(int policyCounter)
- {
- if (policyCounter != 0)
- {
- return policyCounter - 1;
- }
-
- return 0;
- }
-
- public Memoable copy()
- {
- return new CertificatePoliciesValidation(0); // TODO:
- }
-
- public void reset(Memoable other)
- {
- CertificatePoliciesValidation v = (CertificatePoliciesValidation)other; // TODO:
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/validations/CertificatePoliciesValidationBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/path/validations/CertificatePoliciesValidationBuilder.java
deleted file mode 100644
index 74b622e1..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/validations/CertificatePoliciesValidationBuilder.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.bouncycastle.cert.path.validations;
-
-import org.bouncycastle.cert.path.CertPath;
-
-public class CertificatePoliciesValidationBuilder
-{
- private boolean isExplicitPolicyRequired;
- private boolean isAnyPolicyInhibited;
- private boolean isPolicyMappingInhibited;
-
- public void setAnyPolicyInhibited(boolean anyPolicyInhibited)
- {
- isAnyPolicyInhibited = anyPolicyInhibited;
- }
-
- public void setExplicitPolicyRequired(boolean explicitPolicyRequired)
- {
- isExplicitPolicyRequired = explicitPolicyRequired;
- }
-
- public void setPolicyMappingInhibited(boolean policyMappingInhibited)
- {
- isPolicyMappingInhibited = policyMappingInhibited;
- }
-
- public CertificatePoliciesValidation build(int pathLen)
- {
- return new CertificatePoliciesValidation(pathLen, isExplicitPolicyRequired, isAnyPolicyInhibited, isPolicyMappingInhibited);
- }
-
- public CertificatePoliciesValidation build(CertPath path)
- {
- return build(path.length());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/validations/KeyUsageValidation.java b/pkix/src/main/java/org/bouncycastle/cert/path/validations/KeyUsageValidation.java
deleted file mode 100644
index 5d9adc82..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/validations/KeyUsageValidation.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.bouncycastle.cert.path.validations;
-
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.KeyUsage;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.path.CertPathValidation;
-import org.bouncycastle.cert.path.CertPathValidationContext;
-import org.bouncycastle.cert.path.CertPathValidationException;
-import org.bouncycastle.util.Memoable;
-
-public class KeyUsageValidation
- implements CertPathValidation
-{
- private boolean isMandatory;
-
- public KeyUsageValidation()
- {
- this(true);
- }
-
- public KeyUsageValidation(boolean isMandatory)
- {
- this.isMandatory = isMandatory;
- }
-
- public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
- throws CertPathValidationException
- {
- context.addHandledExtension(Extension.keyUsage);
-
- if (!context.isEndEntity())
- {
- KeyUsage usage = KeyUsage.fromExtensions(certificate.getExtensions());
-
- if (usage != null)
- {
- if (!usage.hasUsages(KeyUsage.keyCertSign))
- {
- throw new CertPathValidationException("Issuer certificate KeyUsage extension does not permit key signing");
- }
- }
- else
- {
- if (isMandatory)
- {
- throw new CertPathValidationException("KeyUsage extension not present in CA certificate");
- }
- }
- }
- }
-
- public Memoable copy()
- {
- return new KeyUsageValidation(isMandatory);
- }
-
- public void reset(Memoable other)
- {
- KeyUsageValidation v = (KeyUsageValidation)other;
-
- this.isMandatory = v.isMandatory;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/validations/ParentCertIssuedValidation.java b/pkix/src/main/java/org/bouncycastle/cert/path/validations/ParentCertIssuedValidation.java
deleted file mode 100644
index a21ad1c4..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/validations/ParentCertIssuedValidation.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package org.bouncycastle.cert.path.validations;
-
-import java.io.IOException;
-
-import org.bouncycastle.asn1.ASN1Encodable;
-import org.bouncycastle.asn1.ASN1Null;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.cert.CertException;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.X509ContentVerifierProviderBuilder;
-import org.bouncycastle.cert.path.CertPathValidation;
-import org.bouncycastle.cert.path.CertPathValidationContext;
-import org.bouncycastle.cert.path.CertPathValidationException;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.util.Memoable;
-
-public class ParentCertIssuedValidation
- implements CertPathValidation
-{
- private X509ContentVerifierProviderBuilder contentVerifierProvider;
-
- private X500Name workingIssuerName;
- private SubjectPublicKeyInfo workingPublicKey;
- private AlgorithmIdentifier workingAlgId;
-
- public ParentCertIssuedValidation(X509ContentVerifierProviderBuilder contentVerifierProvider)
- {
- this.contentVerifierProvider = contentVerifierProvider;
- }
-
- public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
- throws CertPathValidationException
- {
- if (workingIssuerName != null)
- {
- if (!workingIssuerName.equals(certificate.getIssuer()))
- {
- throw new CertPathValidationException("Certificate issue does not match parent");
- }
- }
-
- if (workingPublicKey != null)
- {
- try
- {
- SubjectPublicKeyInfo validatingKeyInfo;
-
- if (workingPublicKey.getAlgorithm().equals(workingAlgId))
- {
- validatingKeyInfo = workingPublicKey;
- }
- else
- {
- validatingKeyInfo = new SubjectPublicKeyInfo(workingAlgId, workingPublicKey.parsePublicKey());
- }
-
- if (!certificate.isSignatureValid(contentVerifierProvider.build(validatingKeyInfo)))
- {
- throw new CertPathValidationException("Certificate signature not for public key in parent");
- }
- }
- catch (OperatorCreationException e)
- {
- throw new CertPathValidationException("Unable to create verifier: " + e.getMessage(), e);
- }
- catch (CertException e)
- {
- throw new CertPathValidationException("Unable to validate signature: " + e.getMessage(), e);
- }
- catch (IOException e)
- {
- throw new CertPathValidationException("Unable to build public key: " + e.getMessage(), e);
- }
- }
-
- workingIssuerName = certificate.getSubject();
- workingPublicKey = certificate.getSubjectPublicKeyInfo();
-
- if (workingAlgId != null)
- {
- // check for inherited parameters
- if (workingPublicKey.getAlgorithm().getAlgorithm().equals(workingAlgId.getAlgorithm()))
- {
- if (!isNull(workingPublicKey.getAlgorithm().getParameters()))
- {
- workingAlgId = workingPublicKey.getAlgorithm();
- }
- }
- else
- {
- workingAlgId = workingPublicKey.getAlgorithm();
- }
- }
- else
- {
- workingAlgId = workingPublicKey.getAlgorithm();
- }
- }
-
- private boolean isNull(ASN1Encodable obj)
- {
- return obj == null || obj instanceof ASN1Null;
- }
-
- public Memoable copy()
- {
- ParentCertIssuedValidation v = new ParentCertIssuedValidation(contentVerifierProvider);
-
- v.workingAlgId = this.workingAlgId;
- v.workingIssuerName = this.workingIssuerName;
- v.workingPublicKey = this.workingPublicKey;
-
- return v;
- }
-
- public void reset(Memoable other)
- {
- ParentCertIssuedValidation v = (ParentCertIssuedValidation)other;
-
- this.contentVerifierProvider = v.contentVerifierProvider;
- this.workingAlgId = v.workingAlgId;
- this.workingIssuerName = v.workingIssuerName;
- this.workingPublicKey = v.workingPublicKey;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/path/validations/ValidationUtils.java b/pkix/src/main/java/org/bouncycastle/cert/path/validations/ValidationUtils.java
deleted file mode 100644
index 2a587065..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/path/validations/ValidationUtils.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.bouncycastle.cert.path.validations;
-
-import org.bouncycastle.cert.X509CertificateHolder;
-
-class ValidationUtils
-{
- static boolean isSelfIssued(X509CertificateHolder cert)
- {
- return cert.getSubject().equals(cert.getIssuer());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/selector/MSOutlookKeyIdCalculator.java b/pkix/src/main/java/org/bouncycastle/cert/selector/MSOutlookKeyIdCalculator.java
deleted file mode 100644
index 8f6d119c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/selector/MSOutlookKeyIdCalculator.java
+++ /dev/null
@@ -1,422 +0,0 @@
-package org.bouncycastle.cert.selector;
-
-import java.io.IOException;
-
-import org.bouncycastle.asn1.ASN1Encoding;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.util.Pack;
-
-class MSOutlookKeyIdCalculator
-{
- // This is less than ideal, but it seems to be the best way of supporting this without exposing SHA-1
- // as the class is only used to workout the MSOutlook Key ID, you can think of the fact it's SHA-1 as
- // a coincidence...
- static byte[] calculateKeyId(SubjectPublicKeyInfo info)
- {
- SHA1Digest dig = new SHA1Digest();
- byte[] hash = new byte[dig.getDigestSize()];
- byte[] spkiEnc = new byte[0];
- try
- {
- spkiEnc = info.getEncoded(ASN1Encoding.DER);
- }
- catch (IOException e)
- {
- return new byte[0];
- }
-
- // try the outlook 2010 calculation
- dig.update(spkiEnc, 0, spkiEnc.length);
-
- dig.doFinal(hash, 0);
-
- return hash;
- }
-
- private static abstract class GeneralDigest
- {
- 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;
- }
- }
-
- protected abstract void processWord(byte[] in, int inOff);
-
- protected abstract void processLength(long bitLength);
-
- protected abstract void processBlock();
- }
-
- private static 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();
- }
-
- 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;
- }
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/selector/X509AttributeCertificateHolderSelector.java b/pkix/src/main/java/org/bouncycastle/cert/selector/X509AttributeCertificateHolderSelector.java
deleted file mode 100644
index c325fbad..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/selector/X509AttributeCertificateHolderSelector.java
+++ /dev/null
@@ -1,268 +0,0 @@
-package org.bouncycastle.cert.selector;
-
-import java.math.BigInteger;
-import java.util.Collection;
-import java.util.Date;
-
-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.asn1.x509.Targets;
-import org.bouncycastle.cert.AttributeCertificateHolder;
-import org.bouncycastle.cert.AttributeCertificateIssuer;
-import org.bouncycastle.cert.X509AttributeCertificateHolder;
-import org.bouncycastle.util.Selector;
-
-/**
- * This class is an <code>Selector</code> 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 <code>true</code> if the attribute certificate is a match
- * <code>false</code> 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<targetss.length; i++)
- {
- Targets t = targetss[i];
- Target[] targets = t.getTargets();
- for (int j=0; j<targets.length; j++)
- {
- if (targetNames.contains(GeneralName.getInstance(targets[j]
- .getTargetName())))
- {
- found = true;
- break;
- }
- }
- }
- if (!found)
- {
- return false;
- }
- }
- if (!targetGroups.isEmpty())
- {
- boolean found = false;
-
- for (int i=0; i<targetss.length; i++)
- {
- Targets t = targetss[i];
- Target[] targets = t.getTargets();
- for (int j=0; j<targets.length; j++)
- {
- if (targetGroups.contains(GeneralName.getInstance(targets[j]
- .getTargetGroup())))
- {
- found = true;
- break;
- }
- }
- }
- if (!found)
- {
- return false;
- }
- }
- }
- }
- return true;
- }
-
- /**
- * Returns a clone of this object.
- *
- * @return the clone.
- */
- public Object clone()
- {
- X509AttributeCertificateHolderSelector sel = new X509AttributeCertificateHolderSelector(
- holder, issuer, serialNumber, attributeCertificateValid, attributeCert, targetNames, targetGroups);
-
- return sel;
- }
-
- /**
- * Returns the attribute certificate holder which must be matched.
- *
- * @return Returns an X509AttributeCertificateHolder
- */
- public X509AttributeCertificateHolder getAttributeCert()
- {
- return attributeCert;
- }
-
- /**
- * Get the criteria for the validity.
- *
- * @return Returns the attributeCertificateValid.
- */
- public Date getAttributeCertificateValid()
- {
- if (attributeCertificateValid != null)
- {
- return new Date(attributeCertificateValid.getTime());
- }
-
- return null;
- }
-
- /**
- * Gets the holder.
- *
- * @return Returns the holder.
- */
- public AttributeCertificateHolder getHolder()
- {
- return holder;
- }
-
- /**
- * Returns the issuer criterion.
- *
- * @return Returns the issuer.
- */
- public AttributeCertificateIssuer getIssuer()
- {
- return issuer;
- }
-
- /**
- * Gets the serial number the attribute certificate must have.
- *
- * @return Returns the serialNumber.
- */
- public BigInteger getSerialNumber()
- {
- return serialNumber;
- }
-
- /**
- * Gets the target names. The collection consists of GeneralName objects.
- * <p>
- * 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.
- * <p>
- * The returned collection is immutable.
- *
- * @return The collection of target groups.
- */
- public Collection getTargetGroups()
- {
- return targetGroups;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/selector/X509AttributeCertificateHolderSelectorBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/selector/X509AttributeCertificateHolderSelectorBuilder.java
deleted file mode 100644
index f9707340..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/selector/X509AttributeCertificateHolderSelectorBuilder.java
+++ /dev/null
@@ -1,194 +0,0 @@
-package 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 <code>null</code> 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 <code>null</code>
- * 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 <code>null</code> 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 <code>null</code>
- * 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
- * <code>null</code> 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 <code>X509AttributeCertificateHolder</code>
- * must contain at least one of the specified target names.
- * <p>
- * 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 <code>null</code>)
- */
- public void addTargetName(GeneralName name)
- {
- targetNames.add(name);
- }
-
- /**
- * Adds a collection with target names criteria. If <code>null</code> is
- * given any will do.
- * <p>
- * 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 <code>X509AttributeCertificateHolder</code>
- * must contain at least one of the specified target groups.
- * <p>
- * 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 <code>null</code>)
- */
- public void addTargetGroup(GeneralName group)
- {
- targetGroups.add(group);
- }
-
- /**
- * Adds a collection with target groups criteria. If <code>null</code> is
- * given any will do.
- * <p>
- * The collection consists of <code>GeneralName</code> objects or <code>byte[]</code representing DER
- * encoded GeneralNames.
- *
- * @param names A collection of target groups.
- * @throws java.io.IOException if a parsing error occurs.
- * @see #addTargetGroup(org.bouncycastle.asn1.x509.GeneralName)
- */
- public void setTargetGroups(Collection names) throws IOException
- {
- targetGroups = extractGeneralNames(names);
- }
-
- 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();)
- {
- temp.add(GeneralName.getInstance(it.next()));
- }
- return temp;
- }
-
- public X509AttributeCertificateHolderSelector build()
- {
- X509AttributeCertificateHolderSelector sel = new X509AttributeCertificateHolderSelector(
- holder, issuer, serialNumber, attributeCertificateValid, attributeCert, Collections.unmodifiableCollection(new HashSet(targetNames)), Collections.unmodifiableCollection(new HashSet(targetGroups)));
-
- return sel;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java b/pkix/src/main/java/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java
deleted file mode 100644
index 5af58606..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/selector/X509CertificateHolderSelector.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java b/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java
deleted file mode 100644
index 13e9e6b4..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package 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());
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
deleted file mode 100644
index 22a35371..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java b/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java
deleted file mode 100644
index b1c2b49a..00000000
--- a/pkix/src/main/java/org/bouncycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package 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;
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/AuthAttributesProvider.java b/pkix/src/main/java/org/bouncycastle/cms/AuthAttributesProvider.java
deleted file mode 100644
index a17325bd..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/AuthAttributesProvider.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.bouncycastle.cms;
-
-import org.bouncycastle.asn1.ASN1Set;
-
-interface AuthAttributesProvider
-{
- ASN1Set getAuthAttributes();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAbsentContent.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAbsentContent.java
deleted file mode 100644
index f256e2a2..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSAbsentContent.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAlgorithm.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAlgorithm.java
deleted file mode 100644
index 70484c87..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSAlgorithm.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package 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;
-
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerationException.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerationException.java
deleted file mode 100644
index e3cab8a5..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerationException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerator.java
deleted file mode 100644
index 528c738b..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerator.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package 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;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedData.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedData.java
deleted file mode 100644
index 010e12c2..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedData.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedGenerator.java
deleted file mode 100644
index 90658574..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedGenerator.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package 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();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedData.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedData.java
deleted file mode 100644
index bd9d5444..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedData.java
+++ /dev/null
@@ -1,260 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-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.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.getAlgorithm().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 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataGenerator.java
deleted file mode 100644
index 82f8294c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataGenerator.java
+++ /dev/null
@@ -1,181 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-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.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.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.
- *
- * <pre>
- * 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()));
- * </pre>
- */
-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;
- }
- });
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataParser.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataParser.java
deleted file mode 100644
index 11c90c67..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataParser.java
+++ /dev/null
@@ -1,348 +0,0 @@
-package 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.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.operator.DigestCalculatorProvider;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.util.Arrays;
-
-/**
- * Parsing class for an CMS Authenticated Data object from an input stream.
- * <p>
- * 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.
- * </p>
- * <p>
- * Example of use - assuming the first recipient matches the private key we have.
- * <pre>
- * 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!!!!");
- * }
- * }
- * </pre>
- * Note: this class does not introduce buffering - if you are processing large files you should create
- * the parser with:
- * <pre>
- * CMSAuthenticatedDataParser ep = new CMSAuthenticatedDataParser(new BufferedInputStream(inputStream, bufSize));
- * </pre>
- * 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?
- //ASN1Integer 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.getEncapsulatedContentInfo();
- 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.getEncapsulatedContentInfo();
- 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 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java
deleted file mode 100644
index f32666d1..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java
+++ /dev/null
@@ -1,310 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.io.IOException;
-import java.io.OutputStream;
-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.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.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.operator.DigestCalculator;
-import org.bouncycastle.operator.MacCalculator;
-import org.bouncycastle.util.io.TeeOutputStream;
-
-/**
- * General class for generating a CMS authenticated-data message stream.
- * <p>
- * A simple example of usage.
- * <pre>
- * 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();
- * </pre>
- */
-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 ASN1Integer(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();
- }
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedGenerator.java
deleted file mode 100644
index 6aadf1ec..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedGenerator.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.util.Arrays;
-
-public class CMSAuthenticatedGenerator
- extends CMSEnvelopedGenerator
-{
- protected CMSAttributeTableGenerator authGen;
- protected CMSAttributeTableGenerator unauthGen;
-
- /**
- * base constructor
- */
- public CMSAuthenticatedGenerator()
- {
- }
-
- 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, Arrays.clone(hash));
- return param;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedData.java b/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedData.java
deleted file mode 100644
index 3e44908d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedData.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-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
- * <pre>
- * CMSCompressedData cd = new CMSCompressedData(inputStream);
- *
- * process(cd.getContent(new ZlibExpanderProvider()));
- * </pre>
- */
-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);
- }
- }
-
- 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
- */
- public ContentInfo toASN1Structure()
- {
- return contentInfo;
- }
-
- /**
- * return the ASN.1 encoded representation of this object.
- */
- public byte[] getEncoded()
- throws IOException
- {
- return contentInfo.getEncoded();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataGenerator.java
deleted file mode 100644
index d50391a1..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataGenerator.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-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.
- * <p>
- * A simple example of usage.
- * <p>
- * <pre>
- * CMSCompressedDataGenerator fact = new CMSCompressedDataGenerator();
- *
- * CMSCompressedData data = fact.generate(content, new ZlibCompressor());
- * </pre>
- */
-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
- */
- 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataParser.java b/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataParser.java
deleted file mode 100644
index c3da87b7..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataParser.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-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.
- * <pre>
- * CMSCompressedDataParser cp = new CMSCompressedDataParser(inputStream);
- *
- * process(cp.getContent(new ZlibExpanderProvider()).getContentStream());
- * </pre>
- * Note: this class does not introduce buffering - if you are processing large files you should create
- * the parser with:
- * <pre>
- * CMSCompressedDataParser ep = new CMSCompressedDataParser(new BufferedInputStream(inputStream, bufSize));
- * </pre>
- * 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);
- }
-
- /**
- * 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataStreamGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataStreamGenerator.java
deleted file mode 100644
index 8a34eb01..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataStreamGenerator.java
+++ /dev/null
@@ -1,165 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.bouncycastle.asn1.ASN1Integer;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.BERSequenceGenerator;
-import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
-import org.bouncycastle.operator.OutputCompressor;
-
-/**
- * General class for generating a compressed CMS message stream.
- * <p>
- * A simple example of usage.
- * </p>
- * <pre>
- * CMSCompressedDataStreamGenerator gen = new CMSCompressedDataStreamGenerator();
- *
- * OutputStream cOut = gen.open(outputStream, new ZlibCompressor());
- *
- * cOut.write(data);
- *
- * cOut.close();
- * </pre>
- */
-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;
- }
-
- /**
- * Open a compressing output stream with the PKCS#7 content type OID of "data".
- *
- * @param out the stream to encode to.
- * @param compressor the type of compressor to use.
- * @return an output stream to write the data be compressed to.
- * @throws IOException
- */
- public OutputStream open(
- OutputStream out,
- OutputCompressor compressor)
- throws IOException
- {
- return open(CMSObjectIdentifiers.data, out, compressor);
- }
-
- /**
- * Open a compressing output stream.
- *
- * @param contentOID the content type OID.
- * @param out the stream to encode to.
- * @param compressor the type of compressor to use.
- * @return an output stream to write the data be compressed to.
- * @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();
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSConfig.java b/pkix/src/main/java/org/bouncycastle/cms/CMSConfig.java
deleted file mode 100644
index fd6782dc..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSConfig.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSContentInfoParser.java b/pkix/src/main/java/org/bouncycastle/cms/CMSContentInfoParser.java
deleted file mode 100644
index a8e5a8da..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSContentInfoParser.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSDigestedData.java b/pkix/src/main/java/org/bouncycastle/cms/CMSDigestedData.java
deleted file mode 100644
index af486923..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSDigestedData.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package 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
- * <pre>
- * CMSDigestedData cd = new CMSDigestedData(inputStream);
- *
- *
- * process(cd.getContent());
- * </pre>
- */
-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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedData.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedData.java
deleted file mode 100644
index f96e7560..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedData.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedDataGenerator.java
deleted file mode 100644
index d12097ee..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedDataGenerator.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package 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.
- *
- * <pre>
- * 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());
- *
- * </pre>
- */
-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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedGenerator.java
deleted file mode 100644
index eece6808..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedGenerator.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedData.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedData.java
deleted file mode 100644
index 56b96635..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedData.java
+++ /dev/null
@@ -1,206 +0,0 @@
-package 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
- * <p>
- * Example of use - assuming the first recipient matches the private key we have.
- * <pre>
- * 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);
- * }
- * </pre>
- */
-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
- */
- 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java
deleted file mode 100644
index 0038f90f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.io.ByteArrayOutputStream;
-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.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.
- *
- * <pre>
- * 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());
- *
- * </pre>
- */
-public class CMSEnvelopedDataGenerator
- extends CMSEnvelopedGenerator
-{
- /**
- * base constructor
- */
- public CMSEnvelopedDataGenerator()
- {
- }
-
- 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataParser.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataParser.java
deleted file mode 100644
index 67c9d913..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataParser.java
+++ /dev/null
@@ -1,208 +0,0 @@
-package 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.
- * <p>
- * 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.
- * </p>
- * <p>
- * Example of use - assuming the first recipient matches the private key we have.
- * <pre>
- * 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());
- * }
- * </pre>
- * Note: this class does not introduce buffering - if you are processing large files you should create
- * the parser with:
- * <pre>
- * CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(new BufferedInputStream(inputStream, bufSize));
- * </pre>
- * 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?
- //ASN1Integer 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java
deleted file mode 100644
index 92abca00..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java
+++ /dev/null
@@ -1,305 +0,0 @@
-package 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.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.
- * <p>
- * A simple example of usage.
- * <pre>
- * 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();
- * </pre>
- */
-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 ASN1Integer getVersion()
- {
- if (originatorInfo != null || _unprotectedAttributes != null)
- {
- return new ASN1Integer(2);
- }
- else
- {
- return new ASN1Integer(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();
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedGenerator.java
deleted file mode 100644
index 012b440a..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedGenerator.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.bouncycastle.cms;
-
-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;
-
- protected OriginatorInfo originatorInfo;
-
- /**
- * base constructor
- */
- public CMSEnvelopedGenerator()
- {
- }
-
- 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedHelper.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedHelper.java
deleted file mode 100644
index 91727062..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedHelper.java
+++ /dev/null
@@ -1,203 +0,0 @@
-package 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();
- }
-
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSException.java b/pkix/src/main/java/org/bouncycastle/cms/CMSException.java
deleted file mode 100644
index 04bbd69c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSProcessable.java b/pkix/src/main/java/org/bouncycastle/cms/CMSProcessable.java
deleted file mode 100644
index 9f34b9a1..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSProcessable.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package 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.
- * <p>
- * Note: this routine may be called multiple times.
- */
- public void write(OutputStream out)
- throws IOException, CMSException;
-
- public Object getContent();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSProcessableByteArray.java b/pkix/src/main/java/org/bouncycastle/cms/CMSProcessableByteArray.java
deleted file mode 100644
index 1c79a941..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSProcessableByteArray.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSProcessableFile.java b/pkix/src/main/java/org/bouncycastle/cms/CMSProcessableFile.java
deleted file mode 100644
index b1e45277..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSProcessableFile.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSProcessableInputStream.java b/pkix/src/main/java/org/bouncycastle/cms/CMSProcessableInputStream.java
deleted file mode 100644
index a73e2329..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSProcessableInputStream.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSReadable.java b/pkix/src/main/java/org/bouncycastle/cms/CMSReadable.java
deleted file mode 100644
index ca867666..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSReadable.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-interface CMSReadable
-{
- public InputStream getInputStream()
- throws IOException, CMSException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSRuntimeException.java b/pkix/src/main/java/org/bouncycastle/cms/CMSRuntimeException.java
deleted file mode 100644
index d9f8acc0..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSRuntimeException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSecureReadable.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSecureReadable.java
deleted file mode 100644
index 620d1236..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSSecureReadable.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-interface CMSSecureReadable
-{
- InputStream getInputStream()
- throws IOException, CMSException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java
deleted file mode 100644
index 59d6ce8b..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package 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);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java
deleted file mode 100644
index b1cd91fd..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package 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);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
deleted file mode 100644
index a17d7909..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
+++ /dev/null
@@ -1,543 +0,0 @@
-package 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...
- *
- * <pre>
- * 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++;
- * }
- * }
- * </pre>
- */
-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 revocations the new CRLs to be used - a collection of X509CRLHolder objects, OtherRevocationInfoFormat, or both.
- * @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 revocations)
- throws CMSException
- {
- //
- // copy
- //
- CMSSignedData cms = new CMSSignedData(signedData);
-
- //
- // replace the certs and revocations 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 (revocations != null)
- {
- ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(revocations));
-
- 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java
deleted file mode 100644
index 5417ce4d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java
+++ /dev/null
@@ -1,232 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-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.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.CMSObjectIdentifiers;
-import org.bouncycastle.asn1.cms.ContentInfo;
-import org.bouncycastle.asn1.cms.SignedData;
-import org.bouncycastle.asn1.cms.SignerInfo;
-
-/**
- * general class for generating a pkcs7-signature message.
- * <p>
- * A simple example of usage, generating a detached signature.
- *
- * <pre>
- * 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);
- * </pre>
- */
-public class CMSSignedDataGenerator
- extends CMSSignedGenerator
-{
- private List signerInfs = new ArrayList();
-
- /**
- * base constructor
- */
- public CMSSignedDataGenerator()
- {
- }
-
- /**
- * Generate a CMS Signed Data object carrying a detached CMS signature.
- *
- * @param content the content to be signed.
- */
- public CMSSignedData generate(
- CMSTypedData content)
- throws CMSException
- {
- return generate(content, false);
- }
-
- /**
- * Generate a CMS Signed Data object which can be carrying a detached CMS signature, or have encapsulated data, depending on the value
- * of the encapsulated parameter.
- *
- * @param content the content to be signed.
- * @param encapsulate true if the content should be encapsulated in the signature, false otherwise.
- */
- 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.getContent() != 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();
- }
-}
-
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataParser.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataParser.java
deleted file mode 100644
index 329f089b..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataParser.java
+++ /dev/null
@@ -1,624 +0,0 @@
-package 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.operator.DigestCalculator;
-import org.bouncycastle.operator.DigestCalculatorProvider;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.util.Store;
-import org.bouncycastle.util.io.Streams;
-
-/**
- * Parsing class for an CMS Signed Data object from an input stream.
- * <p>
- * 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.
- * </p>
- * <p>
- * A simple example of usage for an encapsulated signature.
- * </p>
- * <p>
- * 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.
- * </p>
- * <pre>
- * 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)));
- * }
- * </pre>
- * Note also: this class does not introduce buffering - if you are processing large files you should create
- * the parser with:
- * <pre>
- * CMSSignedDataParser ep = new CMSSignedDataParser(new BufferedInputStream(encapSigData, bufSize));
- * </pre>
- * 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 ASN1Set _certSet, _crlSet;
- private boolean _isCertCrlParsed;
-
- 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));
- }
-
- /**
- * 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);
- }
- }
-
- /**
- * 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.
- * <p>
- * The output stream is returned unclosed.
- * </p>
- * @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.
- * <p>
- * The output stream is returned unclosed.
- * </p>
- * @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());
-// }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataStreamGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataStreamGenerator.java
deleted file mode 100644
index 1e09b481..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataStreamGenerator.java
+++ /dev/null
@@ -1,486 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.io.IOException;
-import java.io.OutputStream;
-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.CMSObjectIdentifiers;
-import org.bouncycastle.asn1.cms.SignerInfo;
-
-/**
- * General class for generating a pkcs7-signature message stream.
- * <p>
- * A simple example of usage.
- * </p>
- * <pre>
- * 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();
- * </pre>
- */
-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);
- }
-
- // 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() == 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();
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java
deleted file mode 100644
index 9fe67790..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedGenerator.java
+++ /dev/null
@@ -1,239 +0,0 @@
-package org.bouncycastle.cms;
-
-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.DERTaggedObject;
-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.x9.X9ObjectIdentifiers;
-import org.bouncycastle.cert.X509AttributeCertificateHolder;
-import org.bouncycastle.cert.X509CRLHolder;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Store;
-
-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();
-
- /**
- * base constructor
- */
- protected CMSSignedGenerator()
- {
- }
-
- 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;
- }
-
- /**
- * 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 pre-calculated 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());
- }
- }
-
- /**
- * Add a generator for a particular signer to this CMS SignedData generator.
- *
- * @param infoGen the generator representing the particular signer.
- */
- 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java
deleted file mode 100644
index 2f98e69f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedHelper.java
+++ /dev/null
@@ -1,253 +0,0 @@
-package org.bouncycastle.cms;
-
-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.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 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignerDigestMismatchException.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignerDigestMismatchException.java
deleted file mode 100644
index 0db54bcb..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignerDigestMismatchException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.bouncycastle.cms;
-
-public class CMSSignerDigestMismatchException
- extends CMSException
-{
- public CMSSignerDigestMismatchException(
- String msg)
- {
- super(msg);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSStreamException.java b/pkix/src/main/java/org/bouncycastle/cms/CMSStreamException.java
deleted file mode 100644
index fff00489..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSStreamException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSTypedData.java b/pkix/src/main/java/org/bouncycastle/cms/CMSTypedData.java
deleted file mode 100644
index f7f0a9cd..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSTypedData.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.bouncycastle.cms;
-
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-
-public interface CMSTypedData
- extends CMSProcessable
-{
- ASN1ObjectIdentifier getContentType();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSTypedStream.java b/pkix/src/main/java/org/bouncycastle/cms/CMSTypedStream.java
deleted file mode 100644
index eda3bde3..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSTypedStream.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package 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;
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java b/pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
deleted file mode 100644
index 41f2c001..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
+++ /dev/null
@@ -1,335 +0,0 @@
-package 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.ASN1Set;
-import org.bouncycastle.asn1.ASN1TaggedObject;
-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.OtherRevocationInfoFormat;
-import org.bouncycastle.asn1.ocsp.OCSPResponse;
-import org.bouncycastle.asn1.ocsp.OCSPResponseStatus;
-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.Strings;
-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 crls = new ArrayList();
-
- try
- {
- for (Iterator it = crlStore.getMatches(null).iterator(); it.hasNext();)
- {
- Object rev = it.next();
-
- if (rev instanceof X509CRLHolder)
- {
- X509CRLHolder c = (X509CRLHolder)rev;
-
- crls.add(c.toASN1Structure());
- }
- else if (rev instanceof OtherRevocationInfoFormat)
- {
- OtherRevocationInfoFormat infoFormat = OtherRevocationInfoFormat.getInstance(rev);
-
- validateInfoFormat(infoFormat);
-
- crls.add(new DERTaggedObject(false, 1, infoFormat));
- }
- else if (rev instanceof ASN1TaggedObject)
- {
- crls.add(rev);
- }
- }
-
- return crls;
- }
- catch (ClassCastException e)
- {
- throw new CMSException("error processing certs", e);
- }
- }
-
- private static void validateInfoFormat(OtherRevocationInfoFormat infoFormat)
- {
- if (CMSObjectIdentifiers.id_ri_ocsp_response.equals(infoFormat.getInfoFormat()))
- {
- OCSPResponse resp = OCSPResponse.getInstance(infoFormat.getInfo());
-
- if (resp.getResponseStatus().getValue().intValue() != OCSPResponseStatus.SUCCESSFUL)
- {
- throw new IllegalArgumentException("cannot add unsuccessful OCSP response to CMS SignedData");
- }
- }
- }
-
- 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();
- OtherRevocationInfoFormat infoFormat = new OtherRevocationInfoFormat(otherRevocationInfoFormat, info);
-
- validateInfoFormat(infoFormat);
-
- others.add(new DERTaggedObject(false, 1, infoFormat));
- }
-
- 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);
- }
- }
-
- static byte[] getPasswordBytes(int scheme, char[] password)
- {
- if (scheme == PasswordRecipient.PKCS5_SCHEME2)
- {
- return PKCS5PasswordToBytes(password);
- }
-
- return PKCS5PasswordToUTF8Bytes(password);
- }
-
- /**
- * 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.
- */
- private 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.
- */
- private static byte[] PKCS5PasswordToUTF8Bytes(
- char[] password)
- {
- if (password != null)
- {
- return Strings.toUTF8ByteArray(password);
- }
- else
- {
- return new byte[0];
- }
- }
-
- 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java b/pkix/src/main/java/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java
deleted file mode 100644
index 6bd8c0ac..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.bouncycastle.cms;
-
-public class CMSVerifierCertificateNotValidException
- extends CMSException
-{
- public CMSVerifierCertificateNotValidException(
- String msg)
- {
- super(msg);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java
deleted file mode 100644
index fb37b4d8..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.util.Enumeration;
-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 = new Hashtable();
-
- for (Enumeration en = table.keys(); en.hasMoreElements();)
- {
- Object key = en.nextElement();
-
- std.put(key, table.get(key));
- }
-
- 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));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
deleted file mode 100644
index 4a94a1f9..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
-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");
- addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1", "PLAIN-ECDSA");
- addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224", "PLAIN-ECDSA");
- addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256", "PLAIN-ECDSA");
- addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384", "PLAIN-ECDSA");
- addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512", "PLAIN-ECDSA");
- addEntries(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160", "PLAIN-ECDSA");
-
- 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java b/pkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
deleted file mode 100644
index 7797f79f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
deleted file mode 100644
index 837edd85..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package org.bouncycastle.cms;
-
-import java.util.Date;
-import java.util.Enumeration;
-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 = copyHashTable(table);
-
- 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));
- }
-
- private static Hashtable copyHashTable(Hashtable paramsMap)
- {
- Hashtable newTable = new Hashtable();
-
- Enumeration keys = paramsMap.keys();
- while (keys.hasMoreElements())
- {
- Object key = keys.nextElement();
- newTable.put(key, paramsMap.get(key));
- }
-
- return newTable;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/KEKRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/KEKRecipient.java
deleted file mode 100644
index b9679b3d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/KEKRecipient.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.bouncycastle.cms;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-
-public interface KEKRecipient
- extends Recipient
-{
- RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentKey)
- throws CMSException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientId.java b/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientId.java
deleted file mode 100644
index daa6c7f4..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientId.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientInfoGenerator.java
deleted file mode 100644
index e3bff3ca..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientInfoGenerator.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package 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);
- }
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientInformation.java b/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientInformation.java
deleted file mode 100644
index 62c65294..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/KEKRecipientInformation.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipient.java
deleted file mode 100644
index 08d83804..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipient.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package 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();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientId.java b/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientId.java
deleted file mode 100644
index c64c6eab..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientId.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInfoGenerator.java
deleted file mode 100644
index 85f5881d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInfoGenerator.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package 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;
-
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInformation.java b/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInformation.java
deleted file mode 100644
index 16c26bde..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInformation.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipient.java
deleted file mode 100644
index b61fbbed..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipient.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.bouncycastle.cms;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-
-public interface KeyTransRecipient
- extends Recipient
-{
- RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentKey)
- throws CMSException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientId.java b/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientId.java
deleted file mode 100644
index f850dcfa..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientId.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientInfoGenerator.java
deleted file mode 100644
index e576f03f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientInfoGenerator.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package 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)));
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientInformation.java b/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientInformation.java
deleted file mode 100644
index d59f4b3e..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/KeyTransRecipientInformation.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/NullOutputStream.java b/pkix/src/main/java/org/bouncycastle/cms/NullOutputStream.java
deleted file mode 100644
index 03c058a5..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/NullOutputStream.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- *
- */
-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
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/OriginatorId.java b/pkix/src/main/java/org/bouncycastle/cms/OriginatorId.java
deleted file mode 100644
index ab38105d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/OriginatorId.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/OriginatorInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/OriginatorInfoGenerator.java
deleted file mode 100644
index 8ea5a920..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/OriginatorInfoGenerator.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package 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));
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/OriginatorInformation.java b/pkix/src/main/java/org/bouncycastle/cms/OriginatorInformation.java
deleted file mode 100644
index 7e9379d6..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/OriginatorInformation.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java
deleted file mode 100644
index c81c3028..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package 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;
-
- byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
- throws CMSException;
-
- RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] derivedKey, byte[] encryptedEncryptedContentKey)
- throws CMSException;
-
- int getPasswordConversionScheme();
-
- char[] getPassword();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientId.java b/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientId.java
deleted file mode 100644
index 95688d73..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientId.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientInfoGenerator.java
deleted file mode 100644
index b570c3cf..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientInfoGenerator.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package 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.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));
- }
-
- byte[] encodedPassword = CMSUtils.getPasswordBytes(schemeID, password);
-
- byte[] derivedKey = calculateDerivedKey(encodedPassword, keyDerivationAlgorithm, keySize);
-
- 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[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
- throws CMSException;
-
- protected abstract byte[] generateEncryptedBytes(AlgorithmIdentifier algorithm, byte[] derivedKey, GenericKey contentEncryptionKey)
- throws CMSException;
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientInformation.java b/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientInformation.java
deleted file mode 100644
index 2eef186a..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/PasswordRecipientInformation.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package 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.x509.AlgorithmIdentifier;
-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 = CMSUtils.getPasswordBytes(pbeRecipient.getPasswordConversionScheme(), pbeRecipient.getPassword());
-
- int keySize = ((Integer)KEYSIZES.get(kekAlgParams.getAlgorithm())).intValue();
-
- byte[] derivedKey = pbeRecipient.calculateDerivedKey(passwordBytes, this.getKeyDerivationAlgorithm(), keySize);
-
- return pbeRecipient.getRecipientOperator(kekAlgParams, messageAlgorithm, derivedKey, info.getEncryptedKey().getOctets());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/Recipient.java b/pkix/src/main/java/org/bouncycastle/cms/Recipient.java
deleted file mode 100644
index 88c88a61..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/Recipient.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.bouncycastle.cms;
-
-public interface Recipient
-{
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/RecipientId.java b/pkix/src/main/java/org/bouncycastle/cms/RecipientId.java
deleted file mode 100644
index fae5a100..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/RecipientId.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package 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();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/RecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/RecipientInfoGenerator.java
deleted file mode 100644
index 6ab41d35..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/RecipientInfoGenerator.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.bouncycastle.cms;
-
-import org.bouncycastle.asn1.cms.RecipientInfo;
-import org.bouncycastle.operator.GenericKey;
-
-public interface RecipientInfoGenerator
-{
- RecipientInfo generate(GenericKey contentEncryptionKey)
- throws CMSException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/RecipientInformation.java b/pkix/src/main/java/org/bouncycastle/cms/RecipientInformation.java
deleted file mode 100644
index 86f9fa30..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/RecipientInformation.java
+++ /dev/null
@@ -1,181 +0,0 @@
-package 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.getAlgorithm().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)
- {
- 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);
- }
- }
-
- /**
- * 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;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/RecipientInformationStore.java b/pkix/src/main/java/org/bouncycastle/cms/RecipientInformationStore.java
deleted file mode 100644
index 5cf80e5d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/RecipientInformationStore.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java b/pkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java
deleted file mode 100644
index 7b3e3e58..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/RecipientOperator.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/SignerId.java b/pkix/src/main/java/org/bouncycastle/cms/SignerId.java
deleted file mode 100644
index 6b53bac7..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/SignerId.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
deleted file mode 100644
index f264729c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
+++ /dev/null
@@ -1,291 +0,0 @@
-package 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.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 SignerIdentifier getSID()
- {
- return signerIdentifier;
- }
-
- public int getGeneratedVersion()
- {
- return 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, 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(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, 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java b/pkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java
deleted file mode 100644
index 7a47a2f8..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/SignerInformation.java b/pkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
deleted file mode 100644
index 7e178d6c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
+++ /dev/null
@@ -1,680 +0,0 @@
-package 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.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.operator.ContentVerifier;
-import org.bouncycastle.operator.DigestCalculator;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.RawContentVerifier;
-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 Arrays.clone(resultDigest);
- }
-
- /**
- * 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 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());
- 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 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 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/SignerInformationStore.java b/pkix/src/main/java/org/bouncycastle/cms/SignerInformationStore.java
deleted file mode 100644
index b65ab5ea..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/SignerInformationStore.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/SignerInformationVerifier.java b/pkix/src/main/java/org/bouncycastle/cms/SignerInformationVerifier.java
deleted file mode 100644
index ada4d0ea..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/SignerInformationVerifier.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/SignerInformationVerifierProvider.java b/pkix/src/main/java/org/bouncycastle/cms/SignerInformationVerifierProvider.java
deleted file mode 100644
index 5568b0ec..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/SignerInformationVerifierProvider.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package 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;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/SimpleAttributeTableGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/SimpleAttributeTableGenerator.java
deleted file mode 100644
index f182431f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/SimpleAttributeTableGenerator.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/BcCMSContentEncryptorBuilder.java b/pkix/src/main/java/org/bouncycastle/cms/bc/BcCMSContentEncryptorBuilder.java
deleted file mode 100644
index a12c66b3..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/BcCMSContentEncryptorBuilder.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package 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());
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/BcKEKEnvelopedRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/bc/BcKEKEnvelopedRecipient.java
deleted file mode 100644
index 5641d82b..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/BcKEKEnvelopedRecipient.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package 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);
- }
- }
- });
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/BcKEKRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/bc/BcKEKRecipient.java
deleted file mode 100644
index a7d5eb76..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/BcKEKRecipient.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/BcKEKRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/bc/BcKEKRecipientInfoGenerator.java
deleted file mode 100644
index 309ad64b..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/BcKEKRecipientInfoGenerator.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/BcKeyTransRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/bc/BcKeyTransRecipient.java
deleted file mode 100644
index 8c698853..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/BcKeyTransRecipient.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/BcKeyTransRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/bc/BcKeyTransRecipientInfoGenerator.java
deleted file mode 100644
index eebbbda4..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/BcKeyTransRecipientInfoGenerator.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package 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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/BcPasswordEnvelopedRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/bc/BcPasswordEnvelopedRecipient.java
deleted file mode 100644
index d3d38cf6..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/BcPasswordEnvelopedRecipient.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package 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);
- }
- }
- });
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/BcPasswordRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/bc/BcPasswordRecipient.java
deleted file mode 100644
index 50f9c6c0..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/BcPasswordRecipient.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.bouncycastle.cms.bc;
-
-import org.bouncycastle.asn1.ASN1OctetString;
-import org.bouncycastle.asn1.pkcs.PBKDF2Params;
-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.generators.PKCS5S2ParametersGenerator;
-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 byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
- throws CMSException
- {
- PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters());
-
- PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
-
- gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue());
-
- return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey();
- }
-
- public int getPasswordConversionScheme()
- {
- return schemeID;
- }
-
- public char[] getPassword()
- {
- return password;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/BcPasswordRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/bc/BcPasswordRecipientInfoGenerator.java
deleted file mode 100644
index 6e1bfdb7..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/BcPasswordRecipientInfoGenerator.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.bouncycastle.cms.bc;
-
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.ASN1OctetString;
-import org.bouncycastle.asn1.pkcs.PBKDF2Params;
-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.generators.PKCS5S2ParametersGenerator;
-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);
- }
-
- protected byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
- throws CMSException
- {
- PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters());
-
- PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
-
- gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue());
-
- return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey();
- }
-
- 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/BcRSAKeyTransEnvelopedRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/bc/BcRSAKeyTransEnvelopedRecipient.java
deleted file mode 100644
index ed933fe6..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/BcRSAKeyTransEnvelopedRecipient.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package 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);
- }
- }
- });
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/BcRSAKeyTransRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/bc/BcRSAKeyTransRecipientInfoGenerator.java
deleted file mode 100644
index b571b9ae..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/BcRSAKeyTransRecipientInfoGenerator.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/BcRSASignerInfoVerifierBuilder.java b/pkix/src/main/java/org/bouncycastle/cms/bc/BcRSASignerInfoVerifierBuilder.java
deleted file mode 100644
index 93abd65e..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/BcRSASignerInfoVerifierBuilder.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/CMSUtils.java b/pkix/src/main/java/org/bouncycastle/cms/bc/CMSUtils.java
deleted file mode 100644
index 8beb36a1..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/CMSUtils.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package 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");
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/bc/EnvelopedDataHelper.java b/pkix/src/main/java/org/bouncycastle/cms/bc/EnvelopedDataHelper.java
deleted file mode 100644
index bb7c3cd6..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/bc/EnvelopedDataHelper.java
+++ /dev/null
@@ -1,378 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/CMSUtils.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/CMSUtils.java
deleted file mode 100644
index 1596caee..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/CMSUtils.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package org.bouncycastle.cms.jcajce;
-
-import java.io.IOException;
-import java.security.AlgorithmParameters;
-import java.security.Provider;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-
-import org.bouncycastle.asn1.ASN1Encodable;
-import org.bouncycastle.asn1.ASN1OctetString;
-import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
-import org.bouncycastle.asn1.x509.Certificate;
-import org.bouncycastle.asn1.x509.Extension;
-import org.bouncycastle.asn1.x509.TBSCertificateStructure;
-import org.bouncycastle.cms.CMSException;
-import org.bouncycastle.jcajce.util.JcaJceUtils;
-
-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(Extension.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());
- }
- }
-
- static ASN1Encodable extractParameters(AlgorithmParameters params)
- throws CMSException
- {
- try
- {
- return JcaJceUtils.extractParameters(params);
- }
- catch (IOException e)
- {
- throw new CMSException("cannot extract parameters: " + e.getMessage(), e);
- }
- }
-
- static void loadParameters(AlgorithmParameters params, ASN1Encodable sParams)
- throws CMSException
- {
- try
- {
- JcaJceUtils.loadParameters(params, sParams);
- }
- catch (IOException e)
- {
- throw new CMSException("error encoding algorithm parameters.", e);
- }
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/DefaultJcaJceExtHelper.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/DefaultJcaJceExtHelper.java
deleted file mode 100644
index c6cd8257..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/DefaultJcaJceExtHelper.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.bouncycastle.cms.jcajce;
-
-import java.security.PrivateKey;
-
-import javax.crypto.SecretKey;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.jcajce.util.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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java
deleted file mode 100644
index b0810515..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java
+++ /dev/null
@@ -1,668 +0,0 @@
-package org.bouncycastle.cms.jcajce;
-
-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.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.DefaultSecretKeySizeProvider;
-import org.bouncycastle.operator.GenericKey;
-import org.bouncycastle.operator.SecretKeySizeProvider;
-import org.bouncycastle.operator.SymmetricKeyUnwrapper;
-import org.bouncycastle.operator.jcajce.JceAsymmetricKeyUnwrapper;
-
-public class EnvelopedDataHelper
-{
- protected static final SecretKeySizeProvider KEY_SIZE_PROVIDER = DefaultSecretKeySizeProvider.INSTANCE;
-
- 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");
- BASE_CIPHER_NAMES.put(PKCSObjectIdentifiers.rc4, "RC4");
-
- CIPHER_ALG_NAMES.put(CMSAlgorithm.DES_CBC, "DES/CBC/PKCS5Padding");
- CIPHER_ALG_NAMES.put(CMSAlgorithm.RC2_CBC, "RC2/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");
- CIPHER_ALG_NAMES.put(PKCSObjectIdentifiers.rc4, "RC4");
-
- 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");
- }
-
- public 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");
- }
-
- public void keySizeCheck(AlgorithmIdentifier keyAlgorithm, Key key)
- throws CMSException
- {
- int expectedKeySize = EnvelopedDataHelper.KEY_SIZE_PROVIDER.getKeySize(keyAlgorithm);
- if (expectedKeySize > 0)
- {
- byte[] keyEnc = null;
-
- try
- {
- keyEnc = key.getEncoded();
- }
- catch (Exception e)
- {
- // ignore - we're using a HSM...
- }
-
- if (keyEnc != null)
- {
- if (keyEnc.length * 8 != expectedKeySize)
- {
- throw new CMSException("Expected key size for algorithm OID not found in recipient.");
- }
- }
- }
- }
-
- 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());
- }
-
- public 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());
-
- CMSUtils.loadParameters(params, sParams);
-
- 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());
-
- CMSUtils.loadParameters(params, sParams);
-
- 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(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 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)
- {
- asn1Params = CMSUtils.extractParameters(params);
- }
- 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaJceExtHelper.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaJceExtHelper.java
deleted file mode 100644
index 3eb54a10..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaJceExtHelper.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.bouncycastle.cms.jcajce;
-
-import java.security.PrivateKey;
-
-import javax.crypto.SecretKey;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.jcajce.util.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);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java
deleted file mode 100644
index a26cbe70..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package 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());
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerId.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerId.java
deleted file mode 100644
index 056f7c06..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerId.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
deleted file mode 100644
index 4a0e7ca4..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package 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));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java
deleted file mode 100644
index a8058398..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java
+++ /dev/null
@@ -1,180 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoGeneratorBuilder.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoGeneratorBuilder.java
deleted file mode 100644
index 0de417aa..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoGeneratorBuilder.java
+++ /dev/null
@@ -1,202 +0,0 @@
-package 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.
- * <p>
- * For example:
- * <pre>
- * 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));
- * </pre>
- * becomes:
- * <pre>
- * CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
- *
- * gen.addSignerInfoGenerator(
- * new JcaSimpleSignerInfoGeneratorBuilder()
- * .setProvider("BC")
- * .build("SHA1withRSA", signKP.getPrivate(), signCert));
- * </pre>
- */
-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();
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java
deleted file mode 100644
index 441f27d2..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java
+++ /dev/null
@@ -1,150 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java
deleted file mode 100644
index 86f59f69..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceAlgorithmIdentifierConverter.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceAlgorithmIdentifierConverter.java
deleted file mode 100644
index 59928f45..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceAlgorithmIdentifierConverter.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package org.bouncycastle.cms.jcajce;
-
-
-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());
-
- CMSUtils.loadParameters(params, algorithmIdentifier.getParameters());
-
- return params;
- }
- catch (NoSuchAlgorithmException e)
- {
- throw new CMSException("can't find parameters for algorithm", e);
- }
- catch (NoSuchProviderException e)
- {
- throw new CMSException("can't find provider for algorithm", e);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
deleted file mode 100644
index 93d8b72c..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package 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 javax.crypto.Cipher;
-import javax.crypto.CipherOutputStream;
-import javax.crypto.KeyGenerator;
-import javax.crypto.SecretKey;
-
-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.operator.DefaultSecretKeySizeProvider;
-import org.bouncycastle.operator.GenericKey;
-import org.bouncycastle.operator.OutputEncryptor;
-import org.bouncycastle.operator.SecretKeySizeProvider;
-import org.bouncycastle.operator.jcajce.JceGenericKey;
-
-public class JceCMSContentEncryptorBuilder
-{
- private static final SecretKeySizeProvider KEY_SIZE_PROVIDER = DefaultSecretKeySizeProvider.INSTANCE;
-
-
- private final ASN1ObjectIdentifier encryptionOID;
- private final int keySize;
-
- private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper());
- private SecureRandom random;
-
- public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID)
- {
- this(encryptionOID, KEY_SIZE_PROVIDER.getKeySize(encryptionOID));
- }
-
- public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID, int keySize)
- {
- this.encryptionOID = encryptionOID;
- this.keySize = keySize;
-
- int fixedSize = KEY_SIZE_PROVIDER.getKeySize(encryptionOID);
-
- if (encryptionOID.equals(PKCSObjectIdentifiers.des_EDE3_CBC))
- {
- if (keySize != 168 && keySize != fixedSize)
- {
- throw new IllegalArgumentException("incorrect keySize for encryptionOID passed to builder.");
- }
- }
- else
- {
- if (fixedSize > 0 && fixedSize != keySize)
- {
- throw new IllegalArgumentException("incorrect keySize for encryptionOID passed to builder.");
- }
- }
- }
-
- 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
- {
- if (encryptionOID.equals(PKCSObjectIdentifiers.des_EDE3_CBC) && keySize == 192)
- {
- keySize = 168;
- }
- 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java
deleted file mode 100644
index d6ba1609..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java
+++ /dev/null
@@ -1,155 +0,0 @@
-package 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;
- }
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKAuthenticatedRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKAuthenticatedRecipient.java
deleted file mode 100644
index eb73555d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKAuthenticatedRecipient.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package 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();
- }
- });
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKEnvelopedRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKEnvelopedRecipient.java
deleted file mode 100644
index a7293794..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKEnvelopedRecipient.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package 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);
- }
- });
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java
deleted file mode 100644
index d0e41644..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipient.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package 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;
- protected boolean validateKeySize = false;
-
- 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;
- }
-
- /**
- * Set validation of retrieved key sizes against the algorithm parameters for the encrypted key where possible - default is off.
- * <p>
- * This setting will not have any affect if the encryption algorithm in the recipient does not specify a particular key size, or
- * if the unwrapper is a HSM and the byte encoding of the unwrapped secret key is not available.
- * </p>
- * @param doValidate true if unwrapped key's should be validated against the content encryption algorithm, false otherwise.
- * @return this recipient.
- */
- public JceKEKRecipient setKeySizeValidation(boolean doValidate)
- {
- this.validateKeySize = doValidate;
-
- return this;
- }
-
- protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedContentEncryptionKey)
- throws CMSException
- {
- SymmetricKeyUnwrapper unwrapper = helper.createSymmetricUnwrapper(keyEncryptionAlgorithm, recipientKey);
-
- try
- {
- Key key = helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedContentEncryptionKey));
-
- if (validateKeySize)
- {
- helper.keySizeCheck(encryptedKeyAlgorithm, key);
- }
-
- return key;
- }
- catch (OperatorException e)
- {
- throw new CMSException("exception unwrapping key: " + e.getMessage(), e);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipientInfoGenerator.java
deleted file mode 100644
index 15ec8ffd..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKEKRecipientInfoGenerator.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeAuthenticatedRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeAuthenticatedRecipient.java
deleted file mode 100644
index d231f56f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeAuthenticatedRecipient.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package 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();
- }
- });
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeEnvelopedRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeEnvelopedRecipient.java
deleted file mode 100644
index fe647d7d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeEnvelopedRecipient.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package 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);
- }
- });
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java
deleted file mode 100644
index 8c41f914..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientId.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientId.java
deleted file mode 100644
index 56911bec..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientId.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java
deleted file mode 100644
index 583ede2d..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java
+++ /dev/null
@@ -1,215 +0,0 @@
-package 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);
- }
- }
- }
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransAuthenticatedRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransAuthenticatedRecipient.java
deleted file mode 100644
index f15aadb0..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransAuthenticatedRecipient.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package 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();
- }
- });
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransEnvelopedRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransEnvelopedRecipient.java
deleted file mode 100644
index 1bc0188f..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransEnvelopedRecipient.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package 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);
- }
- });
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java
deleted file mode 100644
index a457ede4..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipient.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package 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();
- protected boolean validateKeySize = false;
-
- 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.
- * <p>
- * For example:
- * <pre>
- * unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
- * </pre>
- * </p>
- * @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;
- }
-
- /**
- * Set validation of retrieved key sizes against the algorithm parameters for the encrypted key where possible - default is off.
- * <p>
- * This setting will not have any affect if the encryption algorithm in the recipient does not specify a particular key size, or
- * if the unwrapper is a HSM and the byte encoding of the unwrapped secret key is not available.
- * </p>
- * @param doValidate true if unwrapped key's should be validated against the content encryption algorithm, false otherwise.
- * @return this recipient.
- */
- public JceKeyTransRecipient setKeySizeValidation(boolean doValidate)
- {
- this.validateKeySize = doValidate;
-
- 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
- {
- Key key = helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey));
-
- if (validateKeySize)
- {
- helper.keySizeCheck(encryptedKeyAlgorithm, key);
- }
-
- return key;
- }
- catch (OperatorException e)
- {
- throw new CMSException("exception unwrapping key: " + e.getMessage(), e);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipientId.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipientId.java
deleted file mode 100644
index 8b44817b..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipientId.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipientInfoGenerator.java
deleted file mode 100644
index 60a2ff20..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyTransRecipientInfoGenerator.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package 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.asn1.x509.AlgorithmIdentifier;
-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));
- }
-
- public JceKeyTransRecipientInfoGenerator(byte[] subjectKeyIdentifier, PublicKey publicKey)
- {
- super(subjectKeyIdentifier, new JceAsymmetricKeyWrapper(publicKey));
- }
-
- /**
- * Create a generator overriding the algorithm type implied by the public key in the certificate passed in.
- *
- * @param recipientCert certificate carrying the public key.
- * @param algorithmIdentifier the identifier and parameters for the encryption algorithm to be used.
- */
- public JceKeyTransRecipientInfoGenerator(X509Certificate recipientCert, AlgorithmIdentifier algorithmIdentifier)
- throws CertificateEncodingException
- {
- super(new IssuerAndSerialNumber(new JcaX509CertificateHolder(recipientCert).toASN1Structure()), new JceAsymmetricKeyWrapper(algorithmIdentifier, recipientCert.getPublicKey()));
- }
-
- /**
- * Create a generator overriding the algorithm type implied by the public key passed in.
- *
- * @param subjectKeyIdentifier the subject key identifier value to associate with the public key.
- * @param algorithmIdentifier the identifier and parameters for the encryption algorithm to be used.
- * @param publicKey the public key to use.
- */
- public JceKeyTransRecipientInfoGenerator(byte[] subjectKeyIdentifier, AlgorithmIdentifier algorithmIdentifier, PublicKey publicKey)
- {
- super(subjectKeyIdentifier, new JceAsymmetricKeyWrapper(algorithmIdentifier, 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.
- * <p>
- * For example:
- * <pre>
- * unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
- * </pre>
- * </p>
- * @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;
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordAuthenticatedRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordAuthenticatedRecipient.java
deleted file mode 100644
index ba873d25..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordAuthenticatedRecipient.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package 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();
- }
- });
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordEnvelopedRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordEnvelopedRecipient.java
deleted file mode 100644
index be741db4..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordEnvelopedRecipient.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package 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);
- }
- });
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordRecipient.java
deleted file mode 100644
index 3c00b5ef..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordRecipient.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package 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.pkcs.PBKDF2Params;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.cms.CMSException;
-import org.bouncycastle.cms.PasswordRecipient;
-import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
-import org.bouncycastle.crypto.params.KeyParameter;
-
-/**
- * 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 byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
- throws CMSException
- {
- PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters());
-
- PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
-
- gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue());
-
- return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey();
- }
-
- public int getPasswordConversionScheme()
- {
- return schemeID;
- }
-
- public char[] getPassword()
- {
- return password;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java
deleted file mode 100644
index fefe016e..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package 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.pkcs.PBKDF2Params;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.cms.CMSException;
-import org.bouncycastle.cms.PasswordRecipientInfoGenerator;
-import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
-import org.bouncycastle.crypto.params.KeyParameter;
-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;
- }
-
- protected byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
- throws CMSException
- {
- PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters());
-
- PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
-
- gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue());
-
- return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey();
- }
-
- 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);
- }
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/NamedJcaJceExtHelper.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/NamedJcaJceExtHelper.java
deleted file mode 100644
index fba72dc7..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/NamedJcaJceExtHelper.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.bouncycastle.cms.jcajce;
-
-import java.security.PrivateKey;
-
-import javax.crypto.SecretKey;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.jcajce.util.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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/ProviderJcaJceExtHelper.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/ProviderJcaJceExtHelper.java
deleted file mode 100644
index f6991a89..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/ProviderJcaJceExtHelper.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package 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.util.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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibCompressor.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibCompressor.java
deleted file mode 100644
index 53da722b..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibCompressor.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java
deleted file mode 100644
index 15729a73..00000000
--- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package 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;
-
- /**
- * Base constructor. Create an expander which will not limit the size of any objects expanded in the stream.
- */
- 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;
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/CCPDRequestBuilder.java b/pkix/src/main/java/org/bouncycastle/dvcs/CCPDRequestBuilder.java
deleted file mode 100644
index d8ed653a..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/CCPDRequestBuilder.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/CCPDRequestData.java b/pkix/src/main/java/org/bouncycastle/dvcs/CCPDRequestData.java
deleted file mode 100644
index d2edada3..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/CCPDRequestData.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package 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.
- * <p/>
- * 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/CPDRequestBuilder.java b/pkix/src/main/java/org/bouncycastle/dvcs/CPDRequestBuilder.java
deleted file mode 100644
index 3d671f2e..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/CPDRequestBuilder.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/CPDRequestData.java b/pkix/src/main/java/org/bouncycastle/dvcs/CPDRequestData.java
deleted file mode 100644
index 026b6011..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/CPDRequestData.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package 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.
- * <p/>
- * 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSConstructionException.java b/pkix/src/main/java/org/bouncycastle/dvcs/DVCSConstructionException.java
deleted file mode 100644
index ec865c86..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSConstructionException.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSException.java b/pkix/src/main/java/org/bouncycastle/dvcs/DVCSException.java
deleted file mode 100644
index c5e3897d..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSMessage.java b/pkix/src/main/java/org/bouncycastle/dvcs/DVCSMessage.java
deleted file mode 100644
index f6db5fac..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSMessage.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package 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();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSParsingException.java b/pkix/src/main/java/org/bouncycastle/dvcs/DVCSParsingException.java
deleted file mode 100644
index a034e38d..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSParsingException.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequest.java b/pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequest.java
deleted file mode 100644
index b82f1f17..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequestBuilder.java b/pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequestBuilder.java
deleted file mode 100644
index aab45707..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequestBuilder.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package 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));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequestData.java b/pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequestData.java
deleted file mode 100644
index 3dbc6ba9..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequestData.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package 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.
- * <p/>
- * 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequestInfo.java b/pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequestInfo.java
deleted file mode 100644
index 4d0767d8..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSRequestInfo.java
+++ /dev/null
@@ -1,237 +0,0 @@
-package 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));
- }
-}
-
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSResponse.java b/pkix/src/main/java/org/bouncycastle/dvcs/DVCSResponse.java
deleted file mode 100644
index ac1a6b7d..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/DVCSResponse.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/MessageImprint.java b/pkix/src/main/java/org/bouncycastle/dvcs/MessageImprint.java
deleted file mode 100644
index 5f4fbc12..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/MessageImprint.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/MessageImprintBuilder.java b/pkix/src/main/java/org/bouncycastle/dvcs/MessageImprintBuilder.java
deleted file mode 100644
index 052d4fe9..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/MessageImprintBuilder.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/SignedDVCSMessageGenerator.java b/pkix/src/main/java/org/bouncycastle/dvcs/SignedDVCSMessageGenerator.java
deleted file mode 100644
index 68be7775..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/SignedDVCSMessageGenerator.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/TargetChain.java b/pkix/src/main/java/org/bouncycastle/dvcs/TargetChain.java
deleted file mode 100644
index 7dca8f8e..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/TargetChain.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/VPKCRequestBuilder.java b/pkix/src/main/java/org/bouncycastle/dvcs/VPKCRequestBuilder.java
deleted file mode 100644
index 51e0307f..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/VPKCRequestBuilder.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/VPKCRequestData.java b/pkix/src/main/java/org/bouncycastle/dvcs/VPKCRequestData.java
deleted file mode 100644
index 9624ef7f..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/VPKCRequestData.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package 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.
- * <p/>
- * 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/VSDRequestBuilder.java b/pkix/src/main/java/org/bouncycastle/dvcs/VSDRequestBuilder.java
deleted file mode 100644
index 52ca3203..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/VSDRequestBuilder.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/dvcs/VSDRequestData.java b/pkix/src/main/java/org/bouncycastle/dvcs/VSDRequestData.java
deleted file mode 100644
index 6823c0f0..00000000
--- a/pkix/src/main/java/org/bouncycastle/dvcs/VSDRequestData.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package 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.
- * <p/>
- * 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/EACCertificateBuilder.java b/pkix/src/main/java/org/bouncycastle/eac/EACCertificateBuilder.java
deleted file mode 100644
index a5b33739..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/EACCertificateBuilder.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/EACCertificateHolder.java b/pkix/src/main/java/org/bouncycastle/eac/EACCertificateHolder.java
deleted file mode 100644
index c5e2033c..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/EACCertificateHolder.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/EACCertificateRequestHolder.java b/pkix/src/main/java/org/bouncycastle/eac/EACCertificateRequestHolder.java
deleted file mode 100644
index 560b7301..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/EACCertificateRequestHolder.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/EACException.java b/pkix/src/main/java/org/bouncycastle/eac/EACException.java
deleted file mode 100644
index b6e02cfa..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/EACException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/EACIOException.java b/pkix/src/main/java/org/bouncycastle/eac/EACIOException.java
deleted file mode 100644
index 8aa480bc..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/EACIOException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/jcajce/DefaultEACHelper.java b/pkix/src/main/java/org/bouncycastle/eac/jcajce/DefaultEACHelper.java
deleted file mode 100644
index d281fb35..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/jcajce/DefaultEACHelper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/jcajce/EACHelper.java b/pkix/src/main/java/org/bouncycastle/eac/jcajce/EACHelper.java
deleted file mode 100644
index 8c42a63d..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/jcajce/EACHelper.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package 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;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/jcajce/JcaPublicKeyConverter.java b/pkix/src/main/java/org/bouncycastle/eac/jcajce/JcaPublicKeyConverter.java
deleted file mode 100644
index f47709b7..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/jcajce/JcaPublicKeyConverter.java
+++ /dev/null
@@ -1,168 +0,0 @@
-package 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!!!");
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/jcajce/NamedEACHelper.java b/pkix/src/main/java/org/bouncycastle/eac/jcajce/NamedEACHelper.java
deleted file mode 100644
index e1af5be9..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/jcajce/NamedEACHelper.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package 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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/eac/jcajce/ProviderEACHelper.java b/pkix/src/main/java/org/bouncycastle/eac/jcajce/ProviderEACHelper.java
deleted file mode 100644
index 5ecfee97..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/jcajce/ProviderEACHelper.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package 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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/eac/operator/EACSignatureVerifier.java b/pkix/src/main/java/org/bouncycastle/eac/operator/EACSignatureVerifier.java
deleted file mode 100644
index 2cd4b50a..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/operator/EACSignatureVerifier.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package 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);
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/eac/operator/EACSigner.java b/pkix/src/main/java/org/bouncycastle/eac/operator/EACSigner.java
deleted file mode 100644
index 999d8124..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/operator/EACSigner.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package 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();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/DefaultEACHelper.java b/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/DefaultEACHelper.java
deleted file mode 100644
index a84fda77..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/DefaultEACHelper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/EACHelper.java b/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/EACHelper.java
deleted file mode 100644
index da756ff5..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/EACHelper.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package 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;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/EACUtil.java b/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/EACUtil.java
deleted file mode 100644
index 5e5942a8..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/EACUtil.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.bouncycastle.eac.operator.jcajce;
-
-class EACUtil
-{
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/JcaEACSignatureVerifierBuilder.java b/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/JcaEACSignatureVerifierBuilder.java
deleted file mode 100644
index 51156423..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/JcaEACSignatureVerifierBuilder.java
+++ /dev/null
@@ -1,181 +0,0 @@
-package 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.ASN1Integer;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-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 ASN1Integer(new BigInteger(1, r)));
- v.add(new ASN1Integer(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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/JcaEACSignerBuilder.java b/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/JcaEACSignerBuilder.java
deleted file mode 100644
index 380ec143..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/JcaEACSignerBuilder.java
+++ /dev/null
@@ -1,234 +0,0 @@
-package 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();
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/NamedEACHelper.java b/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/NamedEACHelper.java
deleted file mode 100644
index 511cfcf2..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/NamedEACHelper.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package 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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/ProviderEACHelper.java b/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/ProviderEACHelper.java
deleted file mode 100644
index 148a41eb..00000000
--- a/pkix/src/main/java/org/bouncycastle/eac/operator/jcajce/ProviderEACHelper.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package 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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/mozilla/SignedPublicKeyAndChallenge.java b/pkix/src/main/java/org/bouncycastle/mozilla/SignedPublicKeyAndChallenge.java
deleted file mode 100644
index f9c4bcad..00000000
--- a/pkix/src/main/java/org/bouncycastle/mozilla/SignedPublicKeyAndChallenge.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package 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.
- * <pre>
- * PublicKeyAndChallenge ::= SEQUENCE {
- * spki SubjectPublicKeyInfo,
- * challenge IA5STRING
- * }
- *
- * SignedPublicKeyAndChallenge ::= SEQUENCE {
- * publicKeyAndChallenge PublicKeyAndChallenge,
- * signatureAlgorithm AlgorithmIdentifier,
- * signature BIT STRING
- * }
- * </pre>
- */
-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");
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/EncryptionException.java b/pkix/src/main/java/org/bouncycastle/openssl/EncryptionException.java
deleted file mode 100644
index 67db2073..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/EncryptionException.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package 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;
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/MiscPEMGenerator.java b/pkix/src/main/java/org/bouncycastle/openssl/MiscPEMGenerator.java
deleted file mode 100644
index 02866883..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/MiscPEMGenerator.java
+++ /dev/null
@@ -1,209 +0,0 @@
-package 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.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.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 ASN1Integer(0));
- v.add(new ASN1Integer(p.getP()));
- v.add(new ASN1Integer(p.getQ()));
- v.add(new ASN1Integer(p.getG()));
-
- BigInteger x = ASN1Integer.getInstance(info.parsePrivateKey()).getValue();
- BigInteger y = p.getG().modPow(x, p.getP());
-
- v.add(new ASN1Integer(y));
- v.add(new ASN1Integer(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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PEMDecryptor.java b/pkix/src/main/java/org/bouncycastle/openssl/PEMDecryptor.java
deleted file mode 100644
index 09cef5b7..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PEMDecryptor.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.bouncycastle.openssl;
-
-public interface PEMDecryptor
-{
- byte[] decrypt(byte[] keyBytes, byte[] iv)
- throws PEMException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PEMDecryptorProvider.java b/pkix/src/main/java/org/bouncycastle/openssl/PEMDecryptorProvider.java
deleted file mode 100644
index b1827cde..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PEMDecryptorProvider.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.bouncycastle.openssl;
-
-import org.bouncycastle.operator.OperatorCreationException;
-
-public interface PEMDecryptorProvider
-{
- PEMDecryptor get(String dekAlgName)
- throws OperatorCreationException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PEMEncryptedKeyPair.java b/pkix/src/main/java/org/bouncycastle/openssl/PEMEncryptedKeyPair.java
deleted file mode 100644
index 4c28f8d1..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PEMEncryptedKeyPair.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PEMEncryptor.java b/pkix/src/main/java/org/bouncycastle/openssl/PEMEncryptor.java
deleted file mode 100644
index 5fb6647a..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PEMEncryptor.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.bouncycastle.openssl;
-
-public interface PEMEncryptor
-{
- String getAlgorithm();
-
- byte[] getIV();
-
- byte[] encrypt(byte[] encoding)
- throws PEMException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PEMException.java b/pkix/src/main/java/org/bouncycastle/openssl/PEMException.java
deleted file mode 100644
index 3753aece..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PEMException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PEMKeyPair.java b/pkix/src/main/java/org/bouncycastle/openssl/PEMKeyPair.java
deleted file mode 100644
index 077934e1..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PEMKeyPair.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PEMKeyPairParser.java b/pkix/src/main/java/org/bouncycastle/openssl/PEMKeyPairParser.java
deleted file mode 100644
index fc0cb041..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PEMKeyPairParser.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.bouncycastle.openssl;
-
-import java.io.IOException;
-
-interface PEMKeyPairParser
-{
- PEMKeyPair parse(byte[] encoding)
- throws IOException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PEMParser.java b/pkix/src/main/java/org/bouncycastle/openssl/PEMParser.java
deleted file mode 100644
index dacdba44..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PEMParser.java
+++ /dev/null
@@ -1,510 +0,0 @@
-package 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.
- * <p>
- * 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.
- * </p>
- */
-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("TRUSTED 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);
- }
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PEMUtilities.java b/pkix/src/main/java/org/bouncycastle/openssl/PEMUtilities.java
deleted file mode 100644
index 71b365a9..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PEMUtilities.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package 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.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(ASN1ObjectIdentifier algOid)
- {
- return PKCS5_SCHEME_1.contains(algOid);
- }
-
- public static boolean isPKCS5Scheme2(ASN1ObjectIdentifier algOid)
- {
- return PKCS5_SCHEME_2.contains(algOid);
- }
-
- public static boolean isPKCS12(ASN1ObjectIdentifier algOid)
- {
- return algOid.getId().startsWith(PKCSObjectIdentifiers.pkcs_12PbeIds.getId());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PEMWriter.java b/pkix/src/main/java/org/bouncycastle/openssl/PEMWriter.java
deleted file mode 100644
index 131d02c4..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PEMWriter.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.bouncycastle.openssl;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
-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.
- * @deprecated use JcaPEMWriter
- */
-public class PEMWriter
- extends PemWriter
-{
- /**
- * Base constructor.
- *
- * @param out output stream to use.
- */
- public PEMWriter(Writer out)
- {
- super(out);
- }
-
- /**
- * @throws IOException
- */
- public void writeObject(
- Object obj)
- throws IOException
- {
- writeObject(obj, null);
- }
-
- /**
- * @param obj
- * @param encryptor
- * @throws IOException
- */
- 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PKCS8Generator.java b/pkix/src/main/java/org/bouncycastle/openssl/PKCS8Generator.java
deleted file mode 100644
index f822cba1..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PKCS8Generator.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.bouncycastle.openssl;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-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.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;
-
- /**
- * Base constructor.
- */
- public PKCS8Generator(PrivateKeyInfo key, OutputEncryptor outputEncryptor)
- {
- this.key = key;
- this.outputEncryptor = outputEncryptor;
- }
-
- public PemObject generate()
- throws PemGenerationException
- {
- 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PasswordException.java b/pkix/src/main/java/org/bouncycastle/openssl/PasswordException.java
deleted file mode 100644
index 89625e78..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PasswordException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.bouncycastle.openssl;
-
-public class PasswordException
- extends PEMException
-{
- public PasswordException(String msg)
- {
- super(msg);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/PasswordFinder.java b/pkix/src/main/java/org/bouncycastle/openssl/PasswordFinder.java
deleted file mode 100644
index fb89cf08..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/PasswordFinder.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.bouncycastle.openssl;
-
-/**
- * call back to allow a password to be fetched when one is requested.
- */
-public interface PasswordFinder
-{
- public char[] getPassword();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaMiscPEMGenerator.java b/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaMiscPEMGenerator.java
deleted file mode 100644
index 6547078d..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaMiscPEMGenerator.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaPEMKeyConverter.java b/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaPEMKeyConverter.java
deleted file mode 100644
index 0107f4a2..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaPEMKeyConverter.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package org.bouncycastle.openssl.jcajce;
-
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.PublicKey;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
-import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
-import org.bouncycastle.openssl.PEMException;
-import org.bouncycastle.openssl.PEMKeyPair;
-
-public class JcaPEMKeyConverter
-{
- private JcaJceHelper helper = new DefaultJcaJceHelper();
-
- private static final Map algorithms = new HashMap();
-
- static
- {
- algorithms.put(X9ObjectIdentifiers.id_ecPublicKey, "ECDSA");
- algorithms.put(PKCSObjectIdentifiers.rsaEncryption, "RSA");
- algorithms.put(X9ObjectIdentifiers.id_dsa, "DSA");
- }
-
- 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
- {
- KeyFactory keyFactory = getKeyFactory(keyPair.getPrivateKeyInfo().getPrivateKeyAlgorithm());
-
- 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
- {
- KeyFactory keyFactory = getKeyFactory(publicKeyInfo.getAlgorithm());
-
- 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
- {
- KeyFactory keyFactory = getKeyFactory(privateKeyInfo.getPrivateKeyAlgorithm());
-
- return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyInfo.getEncoded()));
- }
- catch (Exception e)
- {
- throw new PEMException("unable to convert key pair: " + e.getMessage(), e);
- }
- }
-
- private KeyFactory getKeyFactory(AlgorithmIdentifier algId)
- throws NoSuchAlgorithmException, NoSuchProviderException
- {
- ASN1ObjectIdentifier algorithm = algId.getAlgorithm();
-
- String algName = (String)algorithms.get(algorithm);
-
- if (algName == null)
- {
- algName = algorithm.getId();
- }
-
- return helper.createKeyFactory(algName);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaPEMWriter.java b/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaPEMWriter.java
deleted file mode 100644
index 423f9500..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaPEMWriter.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.bouncycastle.openssl.jcajce;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.bouncycastle.openssl.PEMEncryptor;
-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 based on JCA/JCE classes.
- */
-public class JcaPEMWriter
- extends PemWriter
-{
- /**
- * Base constructor.
- *
- * @param out output stream to use.
- */
- public JcaPEMWriter(Writer out)
- {
- super(out);
- }
-
- /**
- * @throws java.io.IOException
- */
- public void writeObject(
- Object obj)
- throws IOException
- {
- writeObject(obj, null);
- }
-
- /**
- * @param obj
- * @param encryptor
- * @throws java.io.IOException
- */
- 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaPKCS8Generator.java b/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaPKCS8Generator.java
deleted file mode 100644
index 261dcecb..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcaPKCS8Generator.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java
deleted file mode 100644
index 46cca30d..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- };
- };
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java b/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java
deleted file mode 100644
index 09f8807b..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java
+++ /dev/null
@@ -1,221 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- };
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcePEMDecryptorProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcePEMDecryptorProviderBuilder.java
deleted file mode 100644
index a9d5c5c5..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcePEMDecryptorProviderBuilder.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.bouncycastle.openssl.jcajce;
-
-import java.security.Provider;
-
-import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- };
- }
- };
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcePEMEncryptorBuilder.java b/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcePEMEncryptorBuilder.java
deleted file mode 100644
index de1de13a..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JcePEMEncryptorBuilder.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.bouncycastle.openssl.jcajce;
-
-import java.security.Provider;
-import java.security.SecureRandom;
-
-import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- };
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/PEMUtilities.java b/pkix/src/main/java/org/bouncycastle/openssl/jcajce/PEMUtilities.java
deleted file mode 100644
index a5a88a90..00000000
--- a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/PEMUtilities.java
+++ /dev/null
@@ -1,257 +0,0 @@
-package 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.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.util.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(ASN1ObjectIdentifier algOid)
- {
- return PKCS5_SCHEME_1.contains(algOid);
- }
-
- static boolean isPKCS5Scheme2(ASN1ObjectIdentifier algOid)
- {
- return PKCS5_SCHEME_2.contains(algOid);
- }
-
- public static boolean isPKCS12(ASN1ObjectIdentifier 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyUnwrapper.java b/pkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyUnwrapper.java
deleted file mode 100644
index 3c3aa2fb..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyUnwrapper.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyWrapper.java b/pkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyWrapper.java
deleted file mode 100644
index 27af7195..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/AsymmetricKeyWrapper.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/BufferingContentSigner.java b/pkix/src/main/java/org/bouncycastle/operator/BufferingContentSigner.java
deleted file mode 100644
index d1743672..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/BufferingContentSigner.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package org.bouncycastle.operator;
-
-import java.io.OutputStream;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.util.io.BufferingOutputStream;
-
-/**
- * A class that explicitly buffers the data to be signed, sending it in one
- * block when ready for signing.
- */
-public class BufferingContentSigner
- implements ContentSigner
-{
- private final ContentSigner contentSigner;
- private final OutputStream output;
-
- /**
- * Base constructor.
- *
- * @param contentSigner the content signer to be wrapped.
- */
- public BufferingContentSigner(ContentSigner contentSigner)
- {
- this.contentSigner = contentSigner;
- this.output = new BufferingOutputStream(contentSigner.getOutputStream());
- }
-
- /**
- * Base constructor.
- *
- * @param contentSigner the content signer to be wrapped.
- * @param bufferSize the size of the internal buffer to use.
- */
- public BufferingContentSigner(ContentSigner contentSigner, int bufferSize)
- {
- this.contentSigner = contentSigner;
- this.output = new BufferingOutputStream(contentSigner.getOutputStream(), bufferSize);
- }
-
- /**
- * Return the algorithm identifier supported by this signer.
- *
- * @return algorithm identifier for the signature generated.
- */
- public AlgorithmIdentifier getAlgorithmIdentifier()
- {
- return contentSigner.getAlgorithmIdentifier();
- }
-
- /**
- * Return the buffering stream.
- *
- * @return the output stream used to accumulate the data.
- */
- public OutputStream getOutputStream()
- {
- return output;
- }
-
- /**
- * Generate signature from internally buffered data.
- *
- * @return the signature calculated from the bytes written to the buffering stream.
- */
- public byte[] getSignature()
- {
- return contentSigner.getSignature();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/ContentSigner.java b/pkix/src/main/java/org/bouncycastle/operator/ContentSigner.java
deleted file mode 100644
index fadef603..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/ContentSigner.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package 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();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/ContentVerifier.java b/pkix/src/main/java/org/bouncycastle/operator/ContentVerifier.java
deleted file mode 100644
index 54d9ef1d..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/ContentVerifier.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package 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);
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/ContentVerifierProvider.java b/pkix/src/main/java/org/bouncycastle/operator/ContentVerifierProvider.java
deleted file mode 100644
index 9594382f..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/ContentVerifierProvider.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package 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;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
deleted file mode 100644
index c03b5d3f..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package 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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeySizeProvider.java b/pkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeySizeProvider.java
deleted file mode 100644
index a1c6ba11..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/DefaultSecretKeySizeProvider.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.bouncycastle.operator;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
-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 DefaultSecretKeySizeProvider
- implements SecretKeySizeProvider
-{
- public static final SecretKeySizeProvider INSTANCE = new DefaultSecretKeySizeProvider();
-
- 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, 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));
-
- keySizes.put(CryptoProObjectIdentifiers.gostR28147_gcfb, Integers.valueOf(256));
-
- KEY_SIZES = Collections.unmodifiableMap(keySizes);
- }
-
- public int getKeySize(AlgorithmIdentifier algorithmIdentifier)
- {
- int keySize = getKeySize(algorithmIdentifier.getAlgorithm());
-
- // just need the OID
- if (keySize > 0)
- {
- return keySize;
- }
-
- // TODO: support OID/Parameter key sizes (e.g. RC2).
-
- return -1;
- }
-
- public int getKeySize(ASN1ObjectIdentifier algorithm)
- {
- Integer keySize = (Integer)KEY_SIZES.get(algorithm);
-
- if (keySize != null)
- {
- return keySize.intValue();
- }
-
- return -1;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
deleted file mode 100644
index 5eb18d45..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package 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.bsi.BSIObjectIdentifiers;
-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.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);
- algorithms.put("SHA1WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA1);
- algorithms.put("SHA224WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA224);
- algorithms.put("SHA256WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA256);
- algorithms.put("SHA384WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA384);
- algorithms.put("SHA512WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA512);
- algorithms.put("RIPEMD160WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_RIPEMD160);
- algorithms.put("SHA1WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1);
- algorithms.put("SHA224WITHPCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_224);
- algorithms.put("SHA256WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_256);
- algorithms.put("SHA384WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_384);
- algorithms.put("SHA512WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_512);
- //
- // 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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java
deleted file mode 100644
index b2d57c60..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/DigestAlgorithmIdentifierFinder.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package 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);
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/DigestCalculator.java b/pkix/src/main/java/org/bouncycastle/operator/DigestCalculator.java
deleted file mode 100644
index 203e876f..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/DigestCalculator.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package 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();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/DigestCalculatorProvider.java b/pkix/src/main/java/org/bouncycastle/operator/DigestCalculatorProvider.java
deleted file mode 100644
index 23652703..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/DigestCalculatorProvider.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.bouncycastle.operator;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-
-public interface DigestCalculatorProvider
-{
- DigestCalculator get(AlgorithmIdentifier digestAlgorithmIdentifier)
- throws OperatorCreationException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/GenericKey.java b/pkix/src/main/java/org/bouncycastle/operator/GenericKey.java
deleted file mode 100644
index c637b667..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/GenericKey.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/InputDecryptor.java b/pkix/src/main/java/org/bouncycastle/operator/InputDecryptor.java
deleted file mode 100644
index 80d7d82a..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/InputDecryptor.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package 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);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/InputDecryptorProvider.java b/pkix/src/main/java/org/bouncycastle/operator/InputDecryptorProvider.java
deleted file mode 100644
index d50e6a7b..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/InputDecryptorProvider.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.bouncycastle.operator;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-
-public interface InputDecryptorProvider
-{
- public InputDecryptor get(AlgorithmIdentifier algorithm)
- throws OperatorCreationException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/InputExpander.java b/pkix/src/main/java/org/bouncycastle/operator/InputExpander.java
deleted file mode 100644
index 4767aed6..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/InputExpander.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package 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);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/InputExpanderProvider.java b/pkix/src/main/java/org/bouncycastle/operator/InputExpanderProvider.java
deleted file mode 100644
index f560e04b..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/InputExpanderProvider.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.bouncycastle.operator;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-
-public interface InputExpanderProvider
-{
- InputExpander get(AlgorithmIdentifier algorithm);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/KeyUnwrapper.java b/pkix/src/main/java/org/bouncycastle/operator/KeyUnwrapper.java
deleted file mode 100644
index e34f6708..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/KeyUnwrapper.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.bouncycastle.operator;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-
-public interface KeyUnwrapper
-{
- AlgorithmIdentifier getAlgorithmIdentifier();
-
- GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptionKeyAlgorithm, byte[] encryptedKey)
- throws OperatorException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/KeyWrapper.java b/pkix/src/main/java/org/bouncycastle/operator/KeyWrapper.java
deleted file mode 100644
index 29b76a84..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/KeyWrapper.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.bouncycastle.operator;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-
-public interface KeyWrapper
-{
- AlgorithmIdentifier getAlgorithmIdentifier();
-
- byte[] generateWrappedKey(GenericKey encryptionKey)
- throws OperatorException;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/MacCalculator.java b/pkix/src/main/java/org/bouncycastle/operator/MacCalculator.java
deleted file mode 100644
index 0572afcb..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/MacCalculator.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package 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();
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/MacCalculatorProvider.java b/pkix/src/main/java/org/bouncycastle/operator/MacCalculatorProvider.java
deleted file mode 100644
index 5f507449..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/MacCalculatorProvider.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.bouncycastle.operator;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-
-public interface MacCalculatorProvider
-{
- public MacCalculator get(AlgorithmIdentifier algorithm);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/OperatorCreationException.java b/pkix/src/main/java/org/bouncycastle/operator/OperatorCreationException.java
deleted file mode 100644
index 06d3fa02..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/OperatorCreationException.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.bouncycastle.operator;
-
-public class OperatorCreationException
- extends OperatorException
-{
- public OperatorCreationException(String msg, Throwable cause)
- {
- super(msg, cause);
- }
-
- public OperatorCreationException(String msg)
- {
- super(msg);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/OperatorException.java b/pkix/src/main/java/org/bouncycastle/operator/OperatorException.java
deleted file mode 100644
index a2146522..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/OperatorException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/OperatorStreamException.java b/pkix/src/main/java/org/bouncycastle/operator/OperatorStreamException.java
deleted file mode 100644
index a4534eba..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/OperatorStreamException.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/OutputCompressor.java b/pkix/src/main/java/org/bouncycastle/operator/OutputCompressor.java
deleted file mode 100644
index 054966ec..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/OutputCompressor.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package 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);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/OutputEncryptor.java b/pkix/src/main/java/org/bouncycastle/operator/OutputEncryptor.java
deleted file mode 100644
index 383e1fd8..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/OutputEncryptor.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package 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();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/RawContentVerifier.java b/pkix/src/main/java/org/bouncycastle/operator/RawContentVerifier.java
deleted file mode 100644
index 447a27b0..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/RawContentVerifier.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package 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);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/RuntimeOperatorException.java b/pkix/src/main/java/org/bouncycastle/operator/RuntimeOperatorException.java
deleted file mode 100644
index 58242b2a..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/RuntimeOperatorException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java b/pkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java
deleted file mode 100644
index 5f92ef03..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/SecretKeySizeProvider.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.bouncycastle.operator;
-
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-
-public interface SecretKeySizeProvider
-{
- int getKeySize(AlgorithmIdentifier algorithmIdentifier);
-
- /**
- * Return the key size implied by the OID, if one exists.
- *
- * @param algorithm the OID of the algorithm of interest.
- * @return -1 if there is no fixed key size associated with the OID, or more information is required.
- */
- int getKeySize(ASN1ObjectIdentifier algorithm);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/SignatureAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/bouncycastle/operator/SignatureAlgorithmIdentifierFinder.java
deleted file mode 100644
index 87521dd6..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/SignatureAlgorithmIdentifierFinder.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package 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);
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/SymmetricKeyUnwrapper.java b/pkix/src/main/java/org/bouncycastle/operator/SymmetricKeyUnwrapper.java
deleted file mode 100644
index 7c724554..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/SymmetricKeyUnwrapper.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/SymmetricKeyWrapper.java b/pkix/src/main/java/org/bouncycastle/operator/SymmetricKeyWrapper.java
deleted file mode 100644
index b1864d23..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/SymmetricKeyWrapper.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/AESUtil.java b/pkix/src/main/java/org/bouncycastle/operator/bc/AESUtil.java
deleted file mode 100644
index 83fab445..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/AESUtil.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package 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
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java
deleted file mode 100644
index 024bbd66..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyWrapper.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyWrapper.java
deleted file mode 100644
index 0da561b0..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcAESSymmetricKeyWrapper.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyUnwrapper.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyUnwrapper.java
deleted file mode 100644
index 2bf5c2d7..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyUnwrapper.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package 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);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyWrapper.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyWrapper.java
deleted file mode 100644
index f9c78087..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcAsymmetricKeyWrapper.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package 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);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcContentSignerBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcContentSignerBuilder.java
deleted file mode 100644
index a7b45fcb..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcContentSignerBuilder.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package 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;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcContentVerifierProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcContentVerifierProviderBuilder.java
deleted file mode 100644
index ff57e60b..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcContentVerifierProviderBuilder.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package 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);
- }
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentSignerBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentSignerBuilder.java
deleted file mode 100644
index 893f9fdd..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentSignerBuilder.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java
deleted file mode 100644
index 15bb3018..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
deleted file mode 100644
index 655b695b..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java
deleted file mode 100644
index 4d029dd8..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcDigestCalculatorProvider.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package 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;
- }
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcDigestProvider.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcDigestProvider.java
deleted file mode 100644
index 691a56ac..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcDigestProvider.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package 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;
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java
deleted file mode 100644
index 84eb29db..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java
deleted file mode 100644
index 9375bd15..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentSignerBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentSignerBuilder.java
deleted file mode 100644
index db317deb..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentSignerBuilder.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java
deleted file mode 100644
index 7b2249c8..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package 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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcSignerOutputStream.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcSignerOutputStream.java
deleted file mode 100644
index 0ef1656b..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcSignerOutputStream.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package 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);
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyUnwrapper.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyUnwrapper.java
deleted file mode 100644
index f8df3b61..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyUnwrapper.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyWrapper.java b/pkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyWrapper.java
deleted file mode 100644
index b7f89505..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/BcSymmetricKeyWrapper.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/CamelliaUtil.java b/pkix/src/main/java/org/bouncycastle/operator/bc/CamelliaUtil.java
deleted file mode 100644
index 819637da..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/CamelliaUtil.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package 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
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/OperatorUtils.java b/pkix/src/main/java/org/bouncycastle/operator/bc/OperatorUtils.java
deleted file mode 100644
index bc8e7f6e..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/OperatorUtils.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package 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");
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/bc/SEEDUtil.java b/pkix/src/main/java/org/bouncycastle/operator/bc/SEEDUtil.java
deleted file mode 100644
index 3b1971c4..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/bc/SEEDUtil.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
deleted file mode 100644
index d4e21621..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package org.bouncycastle.operator.jcajce;
-
-
-import java.io.IOException;
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.MGF1ParameterSpec;
-
-import javax.crypto.spec.OAEPParameterSpec;
-import javax.crypto.spec.PSource;
-
-import org.bouncycastle.asn1.ASN1Encodable;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.DEROctetString;
-import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-import org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
-
-public class JcaAlgorithmParametersConverter
-{
- public JcaAlgorithmParametersConverter()
- {
- }
-
- public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algId, AlgorithmParameters parameters)
- throws InvalidAlgorithmParameterException
- {
- try
- {
- ASN1Encodable params = ASN1Primitive.fromByteArray(parameters.getEncoded());
-
- return new AlgorithmIdentifier(algId, params);
- }
- catch (IOException e)
- {
- throw new InvalidAlgorithmParameterException("unable to encode parameters object: " + e.getMessage());
- }
- }
-
- public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algorithm, AlgorithmParameterSpec algorithmSpec)
- throws InvalidAlgorithmParameterException
- {
- if (algorithmSpec instanceof OAEPParameterSpec)
- {
- if (algorithmSpec.equals(OAEPParameterSpec.DEFAULT))
- {
- return new AlgorithmIdentifier(algorithm,
- new RSAESOAEPparams(RSAESOAEPparams.DEFAULT_HASH_ALGORITHM, RSAESOAEPparams.DEFAULT_MASK_GEN_FUNCTION, RSAESOAEPparams.DEFAULT_P_SOURCE_ALGORITHM));
- }
- else
- {
- OAEPParameterSpec oaepSpec = (OAEPParameterSpec)algorithmSpec;
- PSource pSource = oaepSpec.getPSource();
-
- if (!oaepSpec.getMGFAlgorithm().equals(OAEPParameterSpec.DEFAULT.getMGFAlgorithm()))
- {
- throw new InvalidAlgorithmParameterException("only " + OAEPParameterSpec.DEFAULT.getMGFAlgorithm() + " mask generator supported.");
- }
-
- AlgorithmIdentifier hashAlgorithm = new DefaultDigestAlgorithmIdentifierFinder().find(oaepSpec.getDigestAlgorithm());
- AlgorithmIdentifier mgf1HashAlgorithm = new DefaultDigestAlgorithmIdentifierFinder().find((((MGF1ParameterSpec)oaepSpec.getMGFParameters()).getDigestAlgorithm()));
- return new AlgorithmIdentifier(algorithm,
- new RSAESOAEPparams(hashAlgorithm, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, mgf1HashAlgorithm),
- new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(((PSource.PSpecified)pSource).getValue()))));
- }
- }
-
- throw new InvalidAlgorithmParameterException("unknown parameter spec passed.");
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
deleted file mode 100644
index 31af916f..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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();
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
deleted file mode 100644
index 14ab78df..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
+++ /dev/null
@@ -1,312 +0,0 @@
-package 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.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
-import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- }
- };
- }
-
- public ContentVerifierProvider build(SubjectPublicKeyInfo publicKey)
- throws OperatorCreationException
- {
- return this.build(helper.convertPublicKey(publicKey));
- }
-
- 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);
- }
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java
deleted file mode 100644
index e3567962..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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();
- }
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
deleted file mode 100644
index 8e0ea75e..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package org.bouncycastle.operator.jcajce;
-
-import java.security.AlgorithmParameters;
-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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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.
- * <p>
- * For example:
- * <pre>
- * unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
- * </pre>
- * </p>
- * @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);
- AlgorithmParameters algParams = helper.createAlgorithmParameters(this.getAlgorithmIdentifier());
-
- try
- {
- if (algParams != null)
- {
- keyCipher.init(Cipher.UNWRAP_MODE, privKey, algParams);
- }
- else
- {
- 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java
deleted file mode 100644
index 6ae402d7..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceAsymmetricKeyWrapper.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package org.bouncycastle.operator.jcajce;
-
-import java.security.AlgorithmParameters;
-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.AlgorithmIdentifier;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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());
- }
-
- /**
- * Create a wrapper, overriding the algorithm type that is stored in the public key.
- *
- * @param algorithmIdentifier identifier for encryption algorithm to be used.
- * @param publicKey the public key to be used.
- */
- public JceAsymmetricKeyWrapper(AlgorithmIdentifier algorithmIdentifier, PublicKey publicKey)
- {
- super(algorithmIdentifier);
-
- this.publicKey = publicKey;
- }
-
- 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.
- * <p>
- * For example:
- * <pre>
- * unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
- * </pre>
- * </p>
- * @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);
- AlgorithmParameters algParams = helper.createAlgorithmParameters(this.getAlgorithmIdentifier());
-
- byte[] encryptedKeyBytes = null;
-
- try
- {
- if (algParams != null)
- {
- keyEncryptionCipher.init(Cipher.WRAP_MODE, publicKey, algParams, random);
- }
- else
- {
- 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceGenericKey.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceGenericKey.java
deleted file mode 100644
index efcbc3dc..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceGenericKey.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package 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));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java
deleted file mode 100644
index b2c9cd3f..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java
deleted file mode 100644
index a8f712a5..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java
+++ /dev/null
@@ -1,154 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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");
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
deleted file mode 100644
index 2e3ea666..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
+++ /dev/null
@@ -1,433 +0,0 @@
-package org.bouncycastle.operator.jcajce;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.security.AlgorithmParameters;
-import java.security.GeneralSecurityException;
-import java.security.KeyFactory;
-import java.security.MessageDigest;
-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.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PSSParameterSpec;
-import java.security.spec.X509EncodedKeySpec;
-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.bsi.BSIObjectIdentifiers;
-import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
-import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
-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.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceUtils;
-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(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512WITHPLAIN-ECDSA");
- oids.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160WITHPLAIN-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1WITHCVC-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224WITHCVC-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256WITHCVC-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384WITHCVC-ECDSA");
- oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512WITHCVC-ECDSA");
-
- 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, "RIPEMD128");
- oids.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD160");
- oids.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD256");
-
- 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);
- }
- }
-
- AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)
- throws OperatorCreationException
- {
- AlgorithmParameters parameters;
-
- if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
- {
- return null;
- }
-
- try
- {
- parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
- }
- catch (NoSuchAlgorithmException e)
- {
- return null; // There's a good chance there aren't any!
- }
- catch (NoSuchProviderException e)
- {
- throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
- }
-
- try
- {
- parameters.init(cipherAlgId.getParameters().toASN1Primitive().getEncoded());
- }
- catch (IOException e)
- {
- throw new OperatorCreationException("cannot initialise algorithm parameters: " + e.getMessage(), e);
- }
-
- return parameters;
- }
-
- MessageDigest createDigest(AlgorithmIdentifier digAlgId)
- throws GeneralSecurityException
- {
- MessageDigest dig;
-
- try
- {
- dig = helper.createDigest(JcaJceUtils.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);
-
- JcaJceUtils.loadParameters(params, algorithm.getParameters());
-
- 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 JcaJceUtils.getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAANDMGF1";
- }
- }
-
- if (oids.containsKey(sigAlgId.getAlgorithm()))
- {
- return (String)oids.get(sigAlgId.getAlgorithm());
- }
-
- return sigAlgId.getAlgorithm().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);
- }
- }
-
- public PublicKey convertPublicKey(SubjectPublicKeyInfo publicKeyInfo)
- throws OperatorCreationException
- {
- try
- {
- KeyFactory keyFact = helper.createKeyFactory(publicKeyInfo.getAlgorithm().getAlgorithm().getId());
-
- return keyFact.generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
- }
- catch (IOException e)
- {
- throw new OperatorCreationException("cannot get encoded form of key: " + e.getMessage(), e);
- }
- catch (NoSuchAlgorithmException e)
- {
- throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
- }
- catch (NoSuchProviderException e)
- {
- throw new OperatorCreationException("cannot find factory provider: " + e.getMessage(), e);
- }
- catch (InvalidKeySpecException e)
- {
- throw new OperatorCreationException("cannot create key factory: " + 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorUtils.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorUtils.java
deleted file mode 100644
index 6c41d960..00000000
--- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorUtils.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package 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");
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/MacDataGenerator.java b/pkix/src/main/java/org/bouncycastle/pkcs/MacDataGenerator.java
deleted file mode 100644
index 7b9daa8b..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/MacDataGenerator.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequest.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequest.java
deleted file mode 100644
index 88e430d4..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequest.java
+++ /dev/null
@@ -1,236 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequestBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequestBuilder.java
deleted file mode 100644
index 851e6970..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS10CertificationRequestBuilder.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package 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.
- * <pre>
- * 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})
- * }
- * </pre>
- */
-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");
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12MacCalculatorBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12MacCalculatorBuilder.java
deleted file mode 100644
index 7f159c6a..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12MacCalculatorBuilder.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package 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();
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12MacCalculatorBuilderProvider.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12MacCalculatorBuilderProvider.java
deleted file mode 100644
index c262ac13..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12MacCalculatorBuilderProvider.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.bouncycastle.pkcs;
-
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-
-public interface PKCS12MacCalculatorBuilderProvider
-{
- PKCS12MacCalculatorBuilder get(AlgorithmIdentifier algorithmIdentifier);
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12PfxPdu.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12PfxPdu.java
deleted file mode 100644
index e39025be..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12PfxPdu.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package 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:
- * <pre>
- * getEncoded(ASN1Encoding.DL)
- * </pre>
- * @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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12PfxPduBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12PfxPduBuilder.java
deleted file mode 100644
index 563ca048..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12PfxPduBuilder.java
+++ /dev/null
@@ -1,179 +0,0 @@
-package 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.
- * <p>
- * For example: you can build a basic key store for the user owning privKey as follows:
- * </p>
- * <pre>
- * 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);
- * </pre>
- *
- */
-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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12SafeBag.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12SafeBag.java
deleted file mode 100644
index 6f053bae..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12SafeBag.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12SafeBagBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12SafeBagBuilder.java
deleted file mode 100644
index 1e3a262d..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12SafeBagBuilder.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package 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)));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12SafeBagFactory.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12SafeBagFactory.java
deleted file mode 100644
index 27738555..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS12SafeBagFactory.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS8EncryptedPrivateKeyInfo.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS8EncryptedPrivateKeyInfo.java
deleted file mode 100644
index 37f1ed84..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS8EncryptedPrivateKeyInfo.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS8EncryptedPrivateKeyInfoBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCS8EncryptedPrivateKeyInfoBuilder.java
deleted file mode 100644
index 653aa571..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCS8EncryptedPrivateKeyInfoBuilder.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package 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.
- * <pre>
- * EncryptedPrivateKeyInfo ::= SEQUENCE {
- * encryptionAlgorithm AlgorithmIdentifier {{KeyEncryptionAlgorithms}},
- * encryptedData EncryptedData
- * }
- *
- * EncryptedData ::= OCTET STRING
- *
- * KeyEncryptionAlgorithms ALGORITHM-IDENTIFIER ::= {
- * ... -- For local profiles
- * }
- * </pre>
- */
-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");
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCSException.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCSException.java
deleted file mode 100644
index 8ee6f6fc..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCSException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/PKCSIOException.java b/pkix/src/main/java/org/bouncycastle/pkcs/PKCSIOException.java
deleted file mode 100644
index c34f739a..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/PKCSIOException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequest.java b/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequest.java
deleted file mode 100644
index 99c337c9..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java
deleted file mode 100644
index 04b0fc60..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package 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));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java
deleted file mode 100644
index d8c38b59..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java b/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java
deleted file mode 100644
index d6f92306..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package 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);
- }
- };
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java
deleted file mode 100644
index e578fd53..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package 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));
- }
- };
- }
- };
-
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java
deleted file mode 100644
index 414c604f..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package 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));
- }
- };
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/bc/PKCS12PBEUtils.java b/pkix/src/main/java/org/bouncycastle/pkcs/bc/PKCS12PBEUtils.java
deleted file mode 100644
index 2edce234..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/bc/PKCS12PBEUtils.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java
deleted file mode 100644
index db57d0ff..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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());
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java
deleted file mode 100644
index 5466e5f7..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS12SafeBagBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS12SafeBagBuilder.java
deleted file mode 100644
index 0af510c2..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS12SafeBagBuilder.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS8EncryptedPrivateKeyInfoBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS8EncryptedPrivateKeyInfoBuilder.java
deleted file mode 100644
index 691288d1..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcaPKCS8EncryptedPrivateKeyInfoBuilder.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilder.java
deleted file mode 100644
index eb52eae1..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilder.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package 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.io.MacOutputStream;
-import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
-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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilderProvider.java b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilderProvider.java
deleted file mode 100644
index ca666d1c..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilderProvider.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package 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.io.MacOutputStream;
-import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
-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);
- }
- };
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java
deleted file mode 100644
index 1b6d0669..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java
+++ /dev/null
@@ -1,177 +0,0 @@
-package 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.ASN1Encodable;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.ASN1OctetString;
-import org.bouncycastle.asn1.cryptopro.GOST28147Parameters;
-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.provider.symmetric.util.BCPBEKey;
-import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
-import org.bouncycastle.jcajce.spec.PBKDF2KeySpec;
-import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
-import org.bouncycastle.operator.DefaultSecretKeySizeProvider;
-import org.bouncycastle.operator.InputDecryptor;
-import org.bouncycastle.operator.InputDecryptorProvider;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.SecretKeySizeProvider;
-
-public class JcePKCSPBEInputDecryptorProviderBuilder
-{
- private JcaJceHelper helper = new DefaultJcaJceHelper();
- private boolean wrongPKCS12Zero = false;
- private SecretKeySizeProvider keySizeProvider = DefaultSecretKeySizeProvider.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());
-
- if (func.isDefaultPrf())
- {
- key = keyFact.generateSecret(new PBEKeySpec(password, func.getSalt(), func.getIterationCount().intValue(), keySizeProvider.getKeySize(encScheme)));
- }
- else
- {
- key = keyFact.generateSecret(new PBKDF2KeySpec(password, func.getSalt(), func.getIterationCount().intValue(), keySizeProvider.getKeySize(encScheme), func.getPrf()));
- }
-
- cipher = helper.createCipher(alg.getEncryptionScheme().getAlgorithm().getId());
-
- encryptionAlg = AlgorithmIdentifier.getInstance(alg.getEncryptionScheme());
-
- ASN1Encodable encParams = alg.getEncryptionScheme().getParameters();
- if (encParams instanceof ASN1OctetString)
- {
- cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ASN1OctetString.getInstance(encParams).getOctets()));
- }
- else
- {
- // TODO: at the moment it's just GOST, but...
- GOST28147Parameters gParams = GOST28147Parameters.getInstance(encParams);
-
- cipher.init(Cipher.DECRYPT_MODE, key, new GOST28147ParameterSpec(gParams.getEncryptionParamSet(), gParams.getIV()));
- }
- }
- }
- 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);
- }
- };
- }
- };
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java b/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java
deleted file mode 100644
index 934bcc0b..00000000
--- a/pkix/src/main/java/org/bouncycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java
+++ /dev/null
@@ -1,179 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
-import org.bouncycastle.operator.DefaultSecretKeySizeProvider;
-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 = DefaultSecretKeySizeProvider.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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/GenTimeAccuracy.java b/pkix/src/main/java/org/bouncycastle/tsp/GenTimeAccuracy.java
deleted file mode 100644
index 3cabb86b..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/GenTimeAccuracy.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.bouncycastle.tsp;
-
-import org.bouncycastle.asn1.ASN1Integer;
-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(
- ASN1Integer 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TSPAlgorithms.java b/pkix/src/main/java/org/bouncycastle/tsp/TSPAlgorithms.java
deleted file mode 100644
index e8b26ad5..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/TSPAlgorithms.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package 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 }));
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TSPException.java b/pkix/src/main/java/org/bouncycastle/tsp/TSPException.java
deleted file mode 100644
index a04e5c52..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/TSPException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TSPIOException.java b/pkix/src/main/java/org/bouncycastle/tsp/TSPIOException.java
deleted file mode 100644
index 0be66dbc..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/TSPIOException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TSPUtil.java b/pkix/src/main/java/org/bouncycastle/tsp/TSPUtil.java
deleted file mode 100644
index d7570717..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/TSPUtil.java
+++ /dev/null
@@ -1,209 +0,0 @@
-package org.bouncycastle.tsp;
-
-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.List;
-import java.util.Map;
-
-import org.bouncycastle.asn1.ASN1Encodable;
-import org.bouncycastle.asn1.ASN1EncodableVector;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-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.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 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 certificate 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.");
- }
- }
-
- 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TSPValidationException.java b/pkix/src/main/java/org/bouncycastle/tsp/TSPValidationException.java
deleted file mode 100644
index 552b302e..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/TSPValidationException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.bouncycastle.tsp;
-
-/**
- * Exception thrown if a TSP request or response fails to validate.
- * <p>
- * 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampRequest.java b/pkix/src/main/java/org/bouncycastle/tsp/TimeStampRequest.java
deleted file mode 100644
index fa7c9f78..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampRequest.java
+++ /dev/null
@@ -1,267 +0,0 @@
-package 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.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
- {
- this(loadRequest(in));
- }
-
- private static TimeStampReq loadRequest(InputStream in)
- throws IOException
- {
- try
- {
- return 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 = ((ASN1ObjectIdentifier)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);
- }
-
- /**
- * 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampRequestGenerator.java b/pkix/src/main/java/org/bouncycastle/tsp/TimeStampRequestGenerator.java
deleted file mode 100644
index 0f9900df..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampRequestGenerator.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponse.java b/pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponse.java
deleted file mode 100644
index 7d135109..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponse.java
+++ /dev/null
@@ -1,189 +0,0 @@
-package 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();
- }
-} \ No newline at end of file
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponseGenerator.java b/pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponseGenerator.java
deleted file mode 100644
index 8ab68aa4..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponseGenerator.java
+++ /dev/null
@@ -1,353 +0,0 @@
-package org.bouncycastle.tsp;
-
-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.ASN1Integer;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.DERBitString;
-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.
- * <p>
- * 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.
- * </p>
- * If you're after the most control with generating a response use:
- * <pre>
- * TimeStampResponse tsResp;
- *
- * try
- * {
- * tsResp = tsRespGen.generateGrantedResponse(request, new BigInteger("23"), new Date());
- * }
- * catch (Exception e)
- * {
- * tsResp = tsRespGen.generateRejectedResponse(e);
- * }
- * </pre>
- * The generate method does this, but provides a status string of "Operation Okay".
- * <p>
- * 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.
- * </p>
- */
-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 ASN1Integer(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.
- * <p>
- * If genTime is null a timeNotAvailable error response will be returned. Calling generate() is the
- * equivalent of:
- * <pre>
- * TimeStampResponse tsResp;
- *
- * try
- * {
- * tsResp = tsRespGen.generateGrantedResponse(request, serialNumber, genTime, "Operation Okay");
- * }
- * catch (Exception e)
- * {
- * tsResp = tsRespGen.generateRejectedResponse(e);
- * }
- * </pre>
- * @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.
- * <p>
- * 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.
- * </p>
- * @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.
- * <p>
- * 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.
- * </p>
- * @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));
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampToken.java b/pkix/src/main/java/org/bouncycastle/tsp/TimeStampToken.java
deleted file mode 100644
index 04229985..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampToken.java
+++ /dev/null
@@ -1,393 +0,0 @@
-package 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.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;
-
-/**
- * Carrier class for a TimeStampToken.
- */
-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.
- * <p>
- * 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.
- * </p>
- * <p>
- * A successful call to validate means all the above are true.
- * </p>
- *
- * @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.
- * <p>
- * Note: this is a much weaker proof of correctness than calling validate().
- * </p>
- *
- * @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();
- }
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenGenerator.java b/pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenGenerator.java
deleted file mode 100644
index 91586c50..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenGenerator.java
+++ /dev/null
@@ -1,380 +0,0 @@
-package org.bouncycastle.tsp;
-
-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.HashMap;
-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.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.asn1.x509.GeneralNames;
-import org.bouncycastle.asn1.x509.IssuerSerial;
-import org.bouncycastle.cert.X509CertificateHolder;
-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.SignerInfoGenerator;
-import org.bouncycastle.operator.DigestCalculator;
-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:
- * <pre>
- * 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;
- * }
- * });
- * </pre>
- */
-public class TimeStampTokenGenerator
-{
- int accuracySeconds = -1;
-
- int accuracyMillis = -1;
-
- int accuracyMicros = -1;
-
- boolean ordering = false;
-
- GeneralName tsa = null;
-
- private ASN1ObjectIdentifier tsaPolicyOID;
-
- private List certs = new ArrayList();
- private List crls = new ArrayList();
- private List attrCerts = new ArrayList();
- private Map otherRevoc = new HashMap();
- 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, digestCalculator, tsaPolicy, false);
- }
-
- /**
- * 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.
- * @param isIssuerSerialIncluded should issuerSerial be included in the ESSCertIDs, true if yes, by default false.
- * @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,
- boolean isIssuerSerialIncluded)
- throws IllegalArgumentException, TSPException
- {
- this.signerInfoGen = signerInfoGen;
- this.tsaPolicyOID = tsaPolicy;
-
- if (!signerInfoGen.hasAssociatedCertificate())
- {
- throw new IllegalArgumentException("SignerInfoGenerator must have an associated certificate");
- }
-
- X509CertificateHolder assocCert = signerInfoGen.getAssociatedCertificate();
- TSPUtil.validateCertificate(assocCert);
-
- try
- {
- OutputStream dOut = digestCalculator.getOutputStream();
-
- dOut.write(assocCert.getEncoded());
-
- dOut.close();
-
- if (digestCalculator.getAlgorithmIdentifier().getAlgorithm().equals(OIWObjectIdentifiers.idSHA1))
- {
- final ESSCertID essCertid = new ESSCertID(digestCalculator.getDigest(),
- isIssuerSerialIncluded ? new IssuerSerial(new GeneralNames(new GeneralName(assocCert.getIssuer())), assocCert.getSerialNumber())
- : null);
-
- 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(),
- isIssuerSerialIncluded ? new IssuerSerial(new GeneralNames(new GeneralName(assocCert.getIssuer())), new ASN1Integer(assocCert.getSerialNumber()))
- : null);
-
- 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));
- }
-
- /**
- * Add a Store of otherRevocationData to the CRL set to be included with the generated TimeStampToken.
- *
- * @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)
- {
- otherRevoc.put(otherRevocationInfoFormat, otherRevocationInfos.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;
- }
-
- /**
- * Generate a TimeStampToken for the passed in request and serialNumber marking it with the passed in genTime.
- *
- * @param request the originating request.
- * @param serialNumber serial number for the TimeStampToken
- * @param genTime token generation time.
- * @return a TimeStampToken
- * @throws TSPException
- */
- public TimeStampToken generate(
- TimeStampRequest request,
- BigInteger serialNumber,
- Date genTime)
- throws TSPException
- {
- 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.addAttributeCertificates(new CollectionStore(attrCerts));
- }
-
- signedDataGenerator.addCRLs(new CollectionStore(crls));
-
- if (!otherRevoc.isEmpty())
- {
- for (Iterator it = otherRevoc.keySet().iterator(); it.hasNext();)
- {
- ASN1ObjectIdentifier format = (ASN1ObjectIdentifier)it.next();
-
- signedDataGenerator.addOtherRevocationInfo(format, new CollectionStore((Collection)otherRevoc.get(format)));
- }
- }
-
- 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenInfo.java b/pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenInfo.java
deleted file mode 100644
index 98011a03..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenInfo.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedData.java b/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedData.java
deleted file mode 100644
index 3093a6d6..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedData.java
+++ /dev/null
@@ -1,204 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataGenerator.java
deleted file mode 100644
index e6f28302..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataGenerator.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package 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)))));
- }
-}
-
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java b/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java
deleted file mode 100644
index 28c7e87a..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java
+++ /dev/null
@@ -1,207 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java b/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java
deleted file mode 100644
index 5cc88668..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/cms/ImprintDigestInvalidException.java b/pkix/src/main/java/org/bouncycastle/tsp/cms/ImprintDigestInvalidException.java
deleted file mode 100644
index 36999978..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/cms/ImprintDigestInvalidException.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/cms/MetaDataUtil.java b/pkix/src/main/java/org/bouncycastle/tsp/cms/MetaDataUtil.java
deleted file mode 100644
index b52f6699..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/cms/MetaDataUtil.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/tsp/cms/TimeStampDataUtil.java b/pkix/src/main/java/org/bouncycastle/tsp/cms/TimeStampDataUtil.java
deleted file mode 100644
index ce115f4e..00000000
--- a/pkix/src/main/java/org/bouncycastle/tsp/cms/TimeStampDataUtil.java
+++ /dev/null
@@ -1,256 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/java/org/bouncycastle/voms/VOMSAttribute.java b/pkix/src/main/java/org/bouncycastle/voms/VOMSAttribute.java
deleted file mode 100644
index 9c062f34..00000000
--- a/pkix/src/main/java/org/bouncycastle/voms/VOMSAttribute.java
+++ /dev/null
@@ -1,242 +0,0 @@
-package 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.<br>
- * <b>NOTE:</b> Cryptographic signatures, time stamps etc. will <b>not</b> 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 <vo>/<host>:<port>
- 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):<br>
- * <code>/vo[/group[/group2...]][/Role=[role]][/Capability=capability]</code>
- */
- 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 <code>&lt;host&gt;:&lt;port&gt;</code>
- * @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();
- }
- }
-}
diff --git a/pkix/src/main/java/org/spongycastle/cert/AttributeCertificateHolder.java b/pkix/src/main/java/org/spongycastle/cert/AttributeCertificateHolder.java
new file mode 100644
index 00000000..610cdbe7
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/AttributeCertificateHolder.java
@@ -0,0 +1,357 @@
+package org.spongycastle.cert;
+
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.Holder;
+import org.spongycastle.asn1.x509.IssuerSerial;
+import org.spongycastle.asn1.x509.ObjectDigestInfo;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.Selector;
+
+/**
+ * The Holder object.
+ *
+ * <pre>
+ * 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
+ * }
+ * </pre>
+ * <p>
+ * <b>Note:</b> If objectDigestInfo comparisons are to be carried out the static
+ * method setDigestCalculatorProvider <b>must</b> be called once to configure the class
+ * to do the necessary calculations.
+ * </p>
+ */
+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.
+ * <p>
+ * <code>digestedObjectType</code> can be one of the following:
+ * <ul>
+ * <li>0 - publicKey - A hash of the public key of the holder must be
+ * passed.
+ * <li>1 - publicKeyCert - A hash of the public key certificate of the
+ * holder must be passed.
+ * <li>2 - otherObjectDigest - A hash of some other object type must be
+ * passed. <code>otherObjectTypeID</code> must not be empty.
+ * </ul>
+ * <p>
+ * 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
+ * <code>digestedObjectType</code> is
+ * <code>otherObjectDigest</code>.
+ * @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.
+ * <p>
+ * <ul>
+ * <li>0 - publicKey - A hash of the public key of the holder must be
+ * passed.
+ * <li>1 - publicKeyCert - A hash of the public key certificate of the
+ * holder must be passed.
+ * <li>2 - otherObjectDigest - A hash of some other object type must be
+ * passed. <code>otherObjectTypeID</code> must not be empty.
+ * </ul>
+ *
+ * @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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/AttributeCertificateIssuer.java b/pkix/src/main/java/org/spongycastle/cert/AttributeCertificateIssuer.java
new file mode 100644
index 00000000..e659e592
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/AttributeCertificateIssuer.java
@@ -0,0 +1,147 @@
+package org.spongycastle.cert;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AttCertIssuer;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.V2Form;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/CertException.java b/pkix/src/main/java/org/spongycastle/cert/CertException.java
new file mode 100644
index 00000000..b394ec89
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/CertException.java
@@ -0,0 +1,27 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/CertIOException.java b/pkix/src/main/java/org/spongycastle/cert/CertIOException.java
new file mode 100644
index 00000000..f21641d6
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/CertIOException.java
@@ -0,0 +1,29 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/CertRuntimeException.java b/pkix/src/main/java/org/spongycastle/cert/CertRuntimeException.java
new file mode 100644
index 00000000..a797083e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/CertRuntimeException.java
@@ -0,0 +1,19 @@
+package org.spongycastle.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;
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/CertUtils.java b/pkix/src/main/java/org/spongycastle/cert/CertUtils.java
new file mode 100644
index 00000000..d03f7843
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/CertUtils.java
@@ -0,0 +1,244 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DEROutputStream;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.AttributeCertificate;
+import org.spongycastle.asn1.x509.AttributeCertificateInfo;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.CertificateList;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.TBSCertList;
+import org.spongycastle.asn1.x509.TBSCertificate;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/X509AttributeCertificateHolder.java b/pkix/src/main/java/org/spongycastle/cert/X509AttributeCertificateHolder.java
new file mode 100644
index 00000000..76c0cdf9
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/X509AttributeCertificateHolder.java
@@ -0,0 +1,366 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DEROutputStream;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.AttCertValidityPeriod;
+import org.spongycastle.asn1.x509.Attribute;
+import org.spongycastle.asn1.x509.AttributeCertificate;
+import org.spongycastle.asn1.x509.AttributeCertificateInfo;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/X509CRLEntryHolder.java b/pkix/src/main/java/org/spongycastle/cert/X509CRLEntryHolder.java
new file mode 100644
index 00000000..da542c0e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/X509CRLEntryHolder.java
@@ -0,0 +1,144 @@
+package org.spongycastle.cert;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.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.
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/X509CRLHolder.java b/pkix/src/main/java/org/spongycastle/cert/X509CRLHolder.java
new file mode 100644
index 00000000..e94c2c1b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/X509CRLHolder.java
@@ -0,0 +1,317 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DEROutputStream;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.CertificateList;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.IssuingDistributionPoint;
+import org.spongycastle.asn1.x509.TBSCertList;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/X509CertificateHolder.java b/pkix/src/main/java/org/spongycastle/cert/X509CertificateHolder.java
new file mode 100644
index 00000000..fd53b92c
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/X509CertificateHolder.java
@@ -0,0 +1,327 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DEROutputStream;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.TBSCertificate;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/X509ContentVerifierProviderBuilder.java b/pkix/src/main/java/org/spongycastle/cert/X509ContentVerifierProviderBuilder.java
new file mode 100644
index 00000000..d8429912
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/X509ContentVerifierProviderBuilder.java
@@ -0,0 +1,14 @@
+package org.spongycastle.cert;
+
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.operator.OperatorCreationException;
+
+public interface X509ContentVerifierProviderBuilder
+{
+ ContentVerifierProvider build(SubjectPublicKeyInfo validatingKeyInfo)
+ throws OperatorCreationException;
+
+ ContentVerifierProvider build(X509CertificateHolder validatingKeyInfo)
+ throws OperatorCreationException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/X509ExtensionUtils.java b/pkix/src/main/java/org/spongycastle/cert/X509ExtensionUtils.java
new file mode 100644
index 00000000..96e603f8
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/X509ExtensionUtils.java
@@ -0,0 +1,132 @@
+package org.spongycastle.cert;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.operator.DigestCalculator;
+
+/**
+ * General utility class for creating calculated extensions using the standard methods.
+ * <p>
+ * <b>Note:</b> This class is not thread safe!
+ * </p>
+ */
+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));
+ }
+
+ public AuthorityKeyIdentifier createAuthorityKeyIdentifier(SubjectPublicKeyInfo publicKeyInfo, GeneralNames generalNames, BigInteger serial)
+ {
+ return new AuthorityKeyIdentifier(calculateIdentifier(publicKeyInfo), generalNames, serial);
+ }
+
+ /**
+ * Return a RFC 3280 type 1 key identifier. As in:
+ * <pre>
+ * (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).
+ * </pre>
+ * @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:
+ * <pre>
+ * (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.
+ * </pre>
+ * @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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/X509v1CertificateBuilder.java b/pkix/src/main/java/org/spongycastle/cert/X509v1CertificateBuilder.java
new file mode 100644
index 00000000..083e1505
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/X509v1CertificateBuilder.java
@@ -0,0 +1,101 @@
+package org.spongycastle.cert;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Locale;
+
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.Time;
+import org.spongycastle.asn1.x509.V1TBSCertificateGenerator;
+import org.spongycastle.asn1.x509.V3TBSCertificateGenerator;
+import org.spongycastle.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)
+ {
+ this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo);
+ }
+
+ /**
+ * Create a builder for a version 1 certificate. You may need to use this constructor if the default locale
+ * doesn't use a Gregorian calender so that the Time produced is compatible with other ASN.1 implementations.
+ *
+ * @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 dateLocale locale to be used for date interpretation.
+ * @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, Locale dateLocale, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
+ {
+ this(issuer, serial, new Time(notBefore, dateLocale), new Time(notAfter, dateLocale), subject, publicKeyInfo);
+ }
+
+ /**
+ * Create a builder for a version 1 certificate.
+ *
+ * @param issuer the certificate issuer
+ * @param serial the certificate serial number
+ * @param notBefore the Time before which the certificate is not valid
+ * @param notAfter the Time 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, Time notBefore, Time 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(notBefore);
+ tbsGen.setEndDate(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());
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/X509v2AttributeCertificateBuilder.java b/pkix/src/main/java/org/spongycastle/cert/X509v2AttributeCertificateBuilder.java
new file mode 100644
index 00000000..ffdd1567
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/X509v2AttributeCertificateBuilder.java
@@ -0,0 +1,162 @@
+package org.spongycastle.cert;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Locale;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.x509.AttCertIssuer;
+import org.spongycastle.asn1.x509.Attribute;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.V2AttributeCertificateInfoGenerator;
+import org.spongycastle.operator.ContentSigner;
+
+/**
+ * class to produce an X.509 Version 2 AttributeCertificate.
+ */
+public class X509v2AttributeCertificateBuilder
+{
+ private V2AttributeCertificateInfoGenerator acInfoGen;
+ private ExtensionsGenerator extGenerator;
+
+ /**
+ * Base constructor.
+ *
+ * @param holder holder certificate details
+ * @param issuer issuer of this attribute certificate.
+ * @param serialNumber serial number of this attribute certificate.
+ * @param notBefore the date before which the certificate is not valid.
+ * @param notAfter the date after which the certificate is not valid.
+ */
+ 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));
+ }
+
+ /**
+ * Base constructor with locale for interpreting dates. You may need to use this constructor if the default locale
+ * doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations.
+ *
+ * @param holder holder certificate details
+ * @param issuer issuer of this attribute certificate.
+ * @param serialNumber serial number of this attribute certificate.
+ * @param notBefore the date before which the certificate is not valid.
+ * @param notAfter the date after which the certificate is not valid.
+ * @param dateLocale locale to be used for date interpretation.
+ */
+ public X509v2AttributeCertificateBuilder(AttributeCertificateHolder holder, AttributeCertificateIssuer issuer, BigInteger serialNumber, Date notBefore, Date notAfter, Locale dateLocale)
+ {
+ 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, dateLocale));
+ acInfoGen.setEndDate(new ASN1GeneralizedTime(notAfter, dateLocale));
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the
+ * extension value.
+ *
+ * @param oid the OID defining the extension type.
+ * @param isCritical true if the extension is critical, false otherwise.
+ * @param encodedValue a byte array representing the encoding of the extension value.
+ * @return this builder object.
+ */
+ public X509v2AttributeCertificateBuilder addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean isCritical,
+ byte[] encodedValue)
+ throws CertIOException
+ {
+ extGenerator.addExtension(oid, isCritical, encodedValue);
+
+ 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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/X509v2CRLBuilder.java b/pkix/src/main/java/org/spongycastle/cert/X509v2CRLBuilder.java
new file mode 100644
index 00000000..69cb2406
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/X509v2CRLBuilder.java
@@ -0,0 +1,266 @@
+package org.spongycastle.cert;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.TBSCertList;
+import org.spongycastle.asn1.x509.Time;
+import org.spongycastle.asn1.x509.V2TBSCertListGenerator;
+import org.spongycastle.asn1.x509.X509Extensions;
+import org.spongycastle.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));
+ }
+
+ /**
+ * Basic constructor with Locale. You may need to use this constructor if the default locale
+ * doesn't use a Gregorian calender so that the Time produced is compatible with other ASN.1 implementations.
+ *
+ * @param issuer the issuer this CRL is associated with.
+ * @param thisUpdate the date of this update.
+ * @param dateLocale locale to be used for date interpretation.
+ */
+ public X509v2CRLBuilder(
+ X500Name issuer,
+ Date thisUpdate,
+ Locale dateLocale)
+ {
+ tbsGen = new V2TBSCertListGenerator();
+ extGenerator = new ExtensionsGenerator();
+
+ tbsGen.setIssuer(issuer);
+ tbsGen.setThisUpdate(new Time(thisUpdate, dateLocale));
+ }
+
+ /**
+ * Basic constructor.
+ *
+ * @param issuer the issuer this CRL is associated with.
+ * @param thisUpdate the Time of this update.
+ */
+ public X509v2CRLBuilder(
+ X500Name issuer,
+ Time thisUpdate)
+ {
+ tbsGen = new V2TBSCertListGenerator();
+ extGenerator = new ExtensionsGenerator();
+
+ tbsGen.setIssuer(issuer);
+ tbsGen.setThisUpdate(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)
+ {
+ return this.setNextUpdate(new Time(date));
+ }
+
+ /**
+ * Set the date by which the next CRL will become available.
+ *
+ * @param date date of next CRL update.
+ * @param dateLocale locale to be used for date interpretation.
+ * @return the current builder.
+ */
+ public X509v2CRLBuilder setNextUpdate(
+ Date date,
+ Locale dateLocale)
+ {
+ return this.setNextUpdate(new Time(date, dateLocale));
+ }
+
+ /**
+ * 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(
+ Time date)
+ {
+ tbsGen.setNextUpdate(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;
+ }
+
+ /**
+ * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the
+ * extension value.
+ *
+ * @param oid the OID defining the extension type.
+ * @param isCritical true if the extension is critical, false otherwise.
+ * @param encodedValue a byte array representing the encoding of the extension value.
+ * @return this builder object.
+ */
+ public X509v2CRLBuilder addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean isCritical,
+ byte[] encodedValue)
+ throws CertIOException
+ {
+ extGenerator.addExtension(oid, isCritical, encodedValue);
+
+ 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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/X509v3CertificateBuilder.java b/pkix/src/main/java/org/spongycastle/cert/X509v3CertificateBuilder.java
new file mode 100644
index 00000000..0b55b2aa
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/X509v3CertificateBuilder.java
@@ -0,0 +1,195 @@
+package org.spongycastle.cert;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Locale;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.Time;
+import org.spongycastle.asn1.x509.V3TBSCertificateGenerator;
+import org.spongycastle.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)
+ {
+ this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo);
+ }
+
+ /**
+ * Create a builder for a version 3 certificate. You may need to use this constructor if the default locale
+ * doesn't use a Gregorian calender so that the Time produced is compatible with other ASN.1 implementations.
+ *
+ * @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 dateLocale locale to be used for date interpretation.
+ * @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, Locale dateLocale, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
+ {
+ this(issuer, serial, new Time(notBefore, dateLocale), new Time(notAfter, dateLocale), subject, publicKeyInfo);
+ }
+
+ /**
+ * Create a builder for a version 3 certificate.
+ *
+ * @param issuer the certificate issuer
+ * @param serial the certificate serial number
+ * @param notBefore the Time before which the certificate is not valid
+ * @param notAfter the Time 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, Time notBefore, Time notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
+ {
+ tbsGen = new V3TBSCertificateGenerator();
+ tbsGen.setSerialNumber(new ASN1Integer(serial));
+ tbsGen.setIssuer(issuer);
+ tbsGen.setStartDate(notBefore);
+ tbsGen.setEndDate(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) using a byte encoding of the
+ * extension value.
+ *
+ * @param oid the OID defining the extension type.
+ * @param isCritical true if the extension is critical, false otherwise.
+ * @param encodedValue a byte array representing the encoding of the extension value.
+ * @return this builder object.
+ */
+ public X509v3CertificateBuilder addExtension(
+ ASN1ObjectIdentifier oid,
+ boolean isCritical,
+ byte[] encodedValue)
+ throws CertIOException
+ {
+ extGenerator.addExtension(oid, isCritical, encodedValue);
+
+ 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());
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/bc/BcX509ExtensionUtils.java b/pkix/src/main/java/org/spongycastle/cert/bc/BcX509ExtensionUtils.java
new file mode 100644
index 00000000..6d4dc217
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/bc/BcX509ExtensionUtils.java
@@ -0,0 +1,91 @@
+package org.spongycastle.cert.bc;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
+import org.spongycastle.cert.X509ExtensionUtils;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.digests.SHA1Digest;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.crypto.util.SubjectPublicKeyInfoFactory;
+import org.spongycastle.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:
+ * <pre>
+ * (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).
+ * </pre>
+ * @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;
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/bc/BcX509v1CertificateBuilder.java b/pkix/src/main/java/org/spongycastle/cert/bc/BcX509v1CertificateBuilder.java
new file mode 100644
index 00000000..2036d5d5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/bc/BcX509v1CertificateBuilder.java
@@ -0,0 +1,33 @@
+package org.spongycastle.cert.bc;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Date;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cert.X509v1CertificateBuilder;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.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));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/bc/BcX509v3CertificateBuilder.java b/pkix/src/main/java/org/spongycastle/cert/bc/BcX509v3CertificateBuilder.java
new file mode 100644
index 00000000..28264101
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/bc/BcX509v3CertificateBuilder.java
@@ -0,0 +1,51 @@
+package org.spongycastle.cert.bc;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Date;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.X509v3CertificateBuilder;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.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));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/cmp/CMPException.java b/pkix/src/main/java/org/spongycastle/cert/cmp/CMPException.java
new file mode 100644
index 00000000..dc02a03b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/cmp/CMPException.java
@@ -0,0 +1,24 @@
+package org.spongycastle.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;
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/cmp/CMPRuntimeException.java b/pkix/src/main/java/org/spongycastle/cert/cmp/CMPRuntimeException.java
new file mode 100644
index 00000000..07f5b819
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/cmp/CMPRuntimeException.java
@@ -0,0 +1,19 @@
+package org.spongycastle.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;
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/cmp/CMPUtil.java b/pkix/src/main/java/org/spongycastle/cert/cmp/CMPUtil.java
new file mode 100644
index 00000000..6198ca84
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/cmp/CMPUtil.java
@@ -0,0 +1,26 @@
+package org.spongycastle.cert.cmp;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/cmp/CertificateConfirmationContent.java b/pkix/src/main/java/org/spongycastle/cert/cmp/CertificateConfirmationContent.java
new file mode 100644
index 00000000..0f860341
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/cmp/CertificateConfirmationContent.java
@@ -0,0 +1,41 @@
+package org.spongycastle.cert.cmp;
+
+import org.spongycastle.asn1.cmp.CertConfirmContent;
+import org.spongycastle.asn1.cmp.CertStatus;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/cmp/CertificateConfirmationContentBuilder.java b/pkix/src/main/java/org/spongycastle/cert/cmp/CertificateConfirmationContentBuilder.java
new file mode 100644
index 00000000..106b3e24
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/cmp/CertificateConfirmationContentBuilder.java
@@ -0,0 +1,78 @@
+package org.spongycastle.cert.cmp;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.cmp.CertConfirmContent;
+import org.spongycastle.asn1.cmp.CertStatus;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.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);
+ }
+
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/cmp/CertificateStatus.java b/pkix/src/main/java/org/spongycastle/cert/cmp/CertificateStatus.java
new file mode 100644
index 00000000..f2923878
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/cmp/CertificateStatus.java
@@ -0,0 +1,60 @@
+package org.spongycastle.cert.cmp;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.cmp.CertStatus;
+import org.spongycastle.asn1.cmp.PKIStatusInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.DigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/cmp/GeneralPKIMessage.java b/pkix/src/main/java/org/spongycastle/cert/cmp/GeneralPKIMessage.java
new file mode 100644
index 00000000..5bd49907
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/cmp/GeneralPKIMessage.java
@@ -0,0 +1,82 @@
+package org.spongycastle.cert.cmp;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.cmp.PKIBody;
+import org.spongycastle.asn1.cmp.PKIHeader;
+import org.spongycastle.asn1.cmp.PKIMessage;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/cmp/ProtectedPKIMessage.java b/pkix/src/main/java/org/spongycastle/cert/cmp/ProtectedPKIMessage.java
new file mode 100644
index 00000000..b5dbb980
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/cmp/ProtectedPKIMessage.java
@@ -0,0 +1,198 @@
+package org.spongycastle.cert.cmp;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.cmp.CMPCertificate;
+import org.spongycastle.asn1.cmp.CMPObjectIdentifiers;
+import org.spongycastle.asn1.cmp.PBMParameter;
+import org.spongycastle.asn1.cmp.PKIBody;
+import org.spongycastle.asn1.cmp.PKIHeader;
+import org.spongycastle.asn1.cmp.PKIMessage;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.crmf.PKMACBuilder;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/cmp/ProtectedPKIMessageBuilder.java b/pkix/src/main/java/org/spongycastle/cert/cmp/ProtectedPKIMessageBuilder.java
new file mode 100644
index 00000000..8d5228d1
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/cmp/ProtectedPKIMessageBuilder.java
@@ -0,0 +1,306 @@
+package org.spongycastle.cert.cmp;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.cmp.CMPCertificate;
+import org.spongycastle.asn1.cmp.InfoTypeAndValue;
+import org.spongycastle.asn1.cmp.PKIBody;
+import org.spongycastle.asn1.cmp.PKIFreeText;
+import org.spongycastle.asn1.cmp.PKIHeader;
+import org.spongycastle.asn1.cmp.PKIHeaderBuilder;
+import org.spongycastle.asn1.cmp.PKIMessage;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/cmp/RevocationDetails.java b/pkix/src/main/java/org/spongycastle/cert/cmp/RevocationDetails.java
new file mode 100644
index 00000000..a9c4993c
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/cmp/RevocationDetails.java
@@ -0,0 +1,36 @@
+package org.spongycastle.cert.cmp;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.cmp.RevDetails;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/cmp/RevocationDetailsBuilder.java b/pkix/src/main/java/org/spongycastle/cert/cmp/RevocationDetailsBuilder.java
new file mode 100644
index 00000000..bc7eaa04
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/cmp/RevocationDetailsBuilder.java
@@ -0,0 +1,59 @@
+package org.spongycastle.cert.cmp;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.cmp.RevDetails;
+import org.spongycastle.asn1.crmf.CertTemplateBuilder;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/AuthenticatorControl.java b/pkix/src/main/java/org/spongycastle/cert/crmf/AuthenticatorControl.java
new file mode 100644
index 00000000..58e6c63a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/AuthenticatorControl.java
@@ -0,0 +1,57 @@
+package org.spongycastle.cert.crmf;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERUTF8String;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/CRMFException.java b/pkix/src/main/java/org/spongycastle/cert/crmf/CRMFException.java
new file mode 100644
index 00000000..14aa0ad2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/CRMFException.java
@@ -0,0 +1,19 @@
+package org.spongycastle.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;
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/CRMFRuntimeException.java b/pkix/src/main/java/org/spongycastle/cert/crmf/CRMFRuntimeException.java
new file mode 100644
index 00000000..cde484c4
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/CRMFRuntimeException.java
@@ -0,0 +1,19 @@
+package org.spongycastle.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;
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/CRMFUtil.java b/pkix/src/main/java/org/spongycastle/cert/crmf/CRMFUtil.java
new file mode 100644
index 00000000..eb6771e6
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/CRMFUtil.java
@@ -0,0 +1,42 @@
+package org.spongycastle.cert.crmf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DEROutputStream;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/CertificateRequestMessage.java b/pkix/src/main/java/org/spongycastle/cert/crmf/CertificateRequestMessage.java
new file mode 100644
index 00000000..987b6b37
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/CertificateRequestMessage.java
@@ -0,0 +1,309 @@
+package org.spongycastle.cert.crmf;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DERUTF8String;
+import org.spongycastle.asn1.crmf.AttributeTypeAndValue;
+import org.spongycastle.asn1.crmf.CRMFObjectIdentifiers;
+import org.spongycastle.asn1.crmf.CertReqMsg;
+import org.spongycastle.asn1.crmf.CertTemplate;
+import org.spongycastle.asn1.crmf.Controls;
+import org.spongycastle.asn1.crmf.PKIArchiveOptions;
+import org.spongycastle.asn1.crmf.PKMACValue;
+import org.spongycastle.asn1.crmf.POPOSigningKey;
+import org.spongycastle.asn1.crmf.ProofOfPossession;
+import org.spongycastle.cert.CertIOException;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.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();
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/CertificateRequestMessageBuilder.java b/pkix/src/main/java/org/spongycastle/cert/crmf/CertificateRequestMessageBuilder.java
new file mode 100644
index 00000000..4bfd6451
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/CertificateRequestMessageBuilder.java
@@ -0,0 +1,279 @@
+package org.spongycastle.cert.crmf;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1Null;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.crmf.AttributeTypeAndValue;
+import org.spongycastle.asn1.crmf.CertReqMsg;
+import org.spongycastle.asn1.crmf.CertRequest;
+import org.spongycastle.asn1.crmf.CertTemplate;
+import org.spongycastle.asn1.crmf.CertTemplateBuilder;
+import org.spongycastle.asn1.crmf.OptionalValidity;
+import org.spongycastle.asn1.crmf.POPOPrivKey;
+import org.spongycastle.asn1.crmf.ProofOfPossession;
+import org.spongycastle.asn1.crmf.SubsequentMessage;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.Time;
+import org.spongycastle.cert.CertIOException;
+import org.spongycastle.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;
+ }
+
+ /**
+ * Request a validity period for the certificate. Either, but not both, of the date parameters may be null.
+ *
+ * @param notBeforeDate not before date for certificate requested.
+ * @param notAfterDate not after date for the certificate requested.
+ *
+ * @return the current builder.
+ */
+ public CertificateRequestMessageBuilder setValidity(Date notBeforeDate, Date notAfterDate)
+ {
+ templateBuilder.setValidity(new OptionalValidity(createTime(notBeforeDate), createTime(notAfterDate)));
+
+ return this;
+ }
+
+ private Time createTime(Date date)
+ {
+ if (date != null)
+ {
+ return new Time(date);
+ }
+
+ return null;
+ }
+
+ 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)));
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/Control.java b/pkix/src/main/java/org/spongycastle/cert/crmf/Control.java
new file mode 100644
index 00000000..4454f7e7
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/Control.java
@@ -0,0 +1,24 @@
+package org.spongycastle.cert.crmf;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.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();
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/EncryptedValueBuilder.java b/pkix/src/main/java/org/spongycastle/cert/crmf/EncryptedValueBuilder.java
new file mode 100644
index 00000000..6a34f49c
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/EncryptedValueBuilder.java
@@ -0,0 +1,133 @@
+package org.spongycastle.cert.crmf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.crmf.EncryptedValue;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.KeyWrapper;
+import org.spongycastle.operator.OperatorException;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/EncryptedValuePadder.java b/pkix/src/main/java/org/spongycastle/cert/crmf/EncryptedValuePadder.java
new file mode 100644
index 00000000..d00b5b62
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/EncryptedValuePadder.java
@@ -0,0 +1,24 @@
+package org.spongycastle.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);
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/EncryptedValueParser.java b/pkix/src/main/java/org/spongycastle/cert/crmf/EncryptedValueParser.java
new file mode 100644
index 00000000..80804993
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/EncryptedValueParser.java
@@ -0,0 +1,103 @@
+package org.spongycastle.cert.crmf;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.crmf.EncryptedValue;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.InputDecryptor;
+import org.spongycastle.util.Strings;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/PKIArchiveControl.java b/pkix/src/main/java/org/spongycastle/cert/crmf/PKIArchiveControl.java
new file mode 100644
index 00000000..0c9bd985
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/PKIArchiveControl.java
@@ -0,0 +1,104 @@
+package org.spongycastle.cert.crmf;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.EnvelopedData;
+import org.spongycastle.asn1.crmf.CRMFObjectIdentifiers;
+import org.spongycastle.asn1.crmf.EncryptedKey;
+import org.spongycastle.asn1.crmf.PKIArchiveOptions;
+import org.spongycastle.cms.CMSEnvelopedData;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/PKIArchiveControlBuilder.java b/pkix/src/main/java/org/spongycastle/cert/crmf/PKIArchiveControlBuilder.java
new file mode 100644
index 00000000..1ca860cb
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/PKIArchiveControlBuilder.java
@@ -0,0 +1,78 @@
+package org.spongycastle.cert.crmf;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.cms.EnvelopedData;
+import org.spongycastle.asn1.crmf.CRMFObjectIdentifiers;
+import org.spongycastle.asn1.crmf.EncKeyWithID;
+import org.spongycastle.asn1.crmf.EncryptedKey;
+import org.spongycastle.asn1.crmf.PKIArchiveOptions;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.cms.CMSEnvelopedData;
+import org.spongycastle.cms.CMSEnvelopedDataGenerator;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.CMSProcessableByteArray;
+import org.spongycastle.cms.RecipientInfoGenerator;
+import org.spongycastle.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)));
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/PKMACBuilder.java b/pkix/src/main/java/org/spongycastle/cert/crmf/PKMACBuilder.java
new file mode 100644
index 00000000..54e9cd91
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/PKMACBuilder.java
@@ -0,0 +1,199 @@
+package org.spongycastle.cert.crmf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.security.SecureRandom;
+
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.cmp.CMPObjectIdentifiers;
+import org.spongycastle.asn1.cmp.PBMParameter;
+import org.spongycastle.asn1.iana.IANAObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.operator.RuntimeOperatorException;
+import org.spongycastle.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);
+ }
+ }
+ };
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/PKMACValueGenerator.java b/pkix/src/main/java/org/spongycastle/cert/crmf/PKMACValueGenerator.java
new file mode 100644
index 00000000..eaf215ff
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/PKMACValueGenerator.java
@@ -0,0 +1,41 @@
+package org.spongycastle.cert.crmf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.crmf.PKMACValue;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/PKMACValueVerifier.java b/pkix/src/main/java/org/spongycastle/cert/crmf/PKMACValueVerifier.java
new file mode 100644
index 00000000..a65ff61d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/PKMACValueVerifier.java
@@ -0,0 +1,43 @@
+package org.spongycastle.cert.crmf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.cmp.PBMParameter;
+import org.spongycastle.asn1.crmf.PKMACValue;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.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());
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/PKMACValuesCalculator.java b/pkix/src/main/java/org/spongycastle/cert/crmf/PKMACValuesCalculator.java
new file mode 100644
index 00000000..0b4f1407
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/PKMACValuesCalculator.java
@@ -0,0 +1,15 @@
+package org.spongycastle.cert.crmf;
+
+import org.spongycastle.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;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java b/pkix/src/main/java/org/spongycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java
new file mode 100644
index 00000000..07659593
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/ProofOfPossessionSigningKeyBuilder.java
@@ -0,0 +1,75 @@
+package org.spongycastle.cert.crmf;
+
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.crmf.CertRequest;
+import org.spongycastle.asn1.crmf.PKMACValue;
+import org.spongycastle.asn1.crmf.POPOSigningKey;
+import org.spongycastle.asn1.crmf.POPOSigningKeyInput;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/RegTokenControl.java b/pkix/src/main/java/org/spongycastle/cert/crmf/RegTokenControl.java
new file mode 100644
index 00000000..b1a6eb7e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/RegTokenControl.java
@@ -0,0 +1,57 @@
+package org.spongycastle.cert.crmf;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERUTF8String;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/ValueDecryptorGenerator.java b/pkix/src/main/java/org/spongycastle/cert/crmf/ValueDecryptorGenerator.java
new file mode 100644
index 00000000..3fcee4eb
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/ValueDecryptorGenerator.java
@@ -0,0 +1,10 @@
+package org.spongycastle.cert.crmf;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.InputDecryptor;
+
+public interface ValueDecryptorGenerator
+{
+ InputDecryptor getValueDecryptor(AlgorithmIdentifier keyAlg, AlgorithmIdentifier symmAlg, byte[] encKey)
+ throws CRMFException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java b/pkix/src/main/java/org/spongycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java
new file mode 100644
index 00000000..756acd7d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java
@@ -0,0 +1,121 @@
+package org.spongycastle.cert.crmf.bc;
+
+import java.security.SecureRandom;
+
+import org.spongycastle.cert.crmf.EncryptedValuePadder;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.digests.SHA1Digest;
+import org.spongycastle.crypto.generators.MGF1BytesGenerator;
+import org.spongycastle.crypto.params.MGFParameters;
+
+/**
+ * An encrypted value padder that uses MGF1 as the basis of the padding.
+ */
+public class BcFixedLengthMGF1Padder
+ 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 BcFixedLengthMGF1Padder(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 BcFixedLengthMGF1Padder(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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/CRMFHelper.java b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/CRMFHelper.java
new file mode 100644
index 00000000..92d7faa6
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/CRMFHelper.java
@@ -0,0 +1,450 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Null;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.iana.IANAObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceUtils;
+
+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
+ {
+ JcaJceUtils.loadParameters(params, sParams);
+ }
+ 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 = JcaJceUtils.extractParameters(params);
+ }
+ 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java
new file mode 100644
index 00000000..9b10e78e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java
@@ -0,0 +1,84 @@
+package org.spongycastle.cert.crmf.jcajce;
+
+import java.io.IOException;
+import java.security.Provider;
+import java.security.PublicKey;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.crmf.CertReqMsg;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.cert.crmf.CertificateRequestMessage;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java
new file mode 100644
index 00000000..1d9318dd
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java
@@ -0,0 +1,57 @@
+package org.spongycastle.cert.crmf.jcajce;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaEncryptedValueBuilder.java b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaEncryptedValueBuilder.java
new file mode 100644
index 00000000..bed393dc
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaEncryptedValueBuilder.java
@@ -0,0 +1,26 @@
+package org.spongycastle.cert.crmf.jcajce;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.crmf.EncryptedValue;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.cert.crmf.EncryptedValueBuilder;
+import org.spongycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.spongycastle.operator.KeyWrapper;
+import org.spongycastle.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));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java
new file mode 100644
index 00000000..de527e07
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java
@@ -0,0 +1,29 @@
+package org.spongycastle.cert.crmf.jcajce;
+
+import java.security.PrivateKey;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java
new file mode 100644
index 00000000..8ad510bb
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java
@@ -0,0 +1,120 @@
+package org.spongycastle.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.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.cert.crmf.ValueDecryptorGenerator;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.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);
+ }
+ };
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java
new file mode 100644
index 00000000..6147184f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java
@@ -0,0 +1,136 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java
new file mode 100644
index 00000000..ceaf78cb
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java
@@ -0,0 +1,69 @@
+package org.spongycastle.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.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.cert.crmf.PKMACValuesCalculator;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/CertHelper.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/CertHelper.java
new file mode 100644
index 00000000..1c5679bf
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/CertHelper.java
@@ -0,0 +1,17 @@
+package org.spongycastle.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;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/DefaultCertHelper.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/DefaultCertHelper.java
new file mode 100644
index 00000000..d8713bf3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/DefaultCertHelper.java
@@ -0,0 +1,14 @@
+package org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaAttrCertStore.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaAttrCertStore.java
new file mode 100644
index 00000000..ed354335
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaAttrCertStore.java
@@ -0,0 +1,62 @@
+package org.spongycastle.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.spongycastle.util.CollectionStore;
+import org.spongycastle.x509.X509AttributeCertificate;
+
+/**
+ * Class for storing Attribute Certificates for later lookup.
+ * <p>
+ * The class will convert X509AttributeCertificate objects into X509AttributeCertificateHolder objects.
+ * </p>
+ */
+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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaAttributeCertificateIssuer.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaAttributeCertificateIssuer.java
new file mode 100644
index 00000000..54ee46ee
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaAttributeCertificateIssuer.java
@@ -0,0 +1,32 @@
+package org.spongycastle.cert.jcajce;
+
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cert.AttributeCertificateIssuer;
+
+public class JcaAttributeCertificateIssuer
+ extends AttributeCertificateIssuer
+{
+ /**
+ * Base constructor.
+ *
+ * @param issuerCert certificate for the issuer of the attribute certificate.
+ */
+ public JcaAttributeCertificateIssuer(X509Certificate issuerCert)
+ {
+ this(issuerCert.getIssuerX500Principal());
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param issuerDN X.500 DN for the issuer of the attribute certificate.
+ */
+ public JcaAttributeCertificateIssuer(X500Principal issuerDN)
+ {
+ super(X500Name.getInstance(issuerDN.getEncoded()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaCRLStore.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaCRLStore.java
new file mode 100644
index 00000000..08493d13
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaCRLStore.java
@@ -0,0 +1,63 @@
+package org.spongycastle.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.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.util.CollectionStore;
+
+/**
+ * Class for storing CRLs for later lookup.
+ * <p>
+ * The class will convert X509CRL objects into X509CRLHolder objects.
+ * </p>
+ */
+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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaCertStore.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaCertStore.java
new file mode 100644
index 00000000..49766814
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaCertStore.java
@@ -0,0 +1,64 @@
+package org.spongycastle.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.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.util.CollectionStore;
+
+/**
+ * Class for storing Certificates for later lookup.
+ * <p>
+ * The class will convert X509Certificate objects into X509CertificateHolder objects.
+ * </p>
+ */
+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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java
new file mode 100644
index 00000000..fbb26cb4
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java
@@ -0,0 +1,148 @@
+package org.spongycastle.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.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX500NameUtil.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX500NameUtil.java
new file mode 100644
index 00000000..d6b6ae89
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX500NameUtil.java
@@ -0,0 +1,29 @@
+package org.spongycastle.cert.jcajce;
+
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509AttributeCertificateHolder.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509AttributeCertificateHolder.java
new file mode 100644
index 00000000..35076252
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509AttributeCertificateHolder.java
@@ -0,0 +1,26 @@
+package org.spongycastle.cert.jcajce;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.x509.AttributeCertificate;
+import org.spongycastle.cert.X509AttributeCertificateHolder;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CRLConverter.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CRLConverter.java
new file mode 100644
index 00000000..7040f1aa
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CRLConverter.java
@@ -0,0 +1,103 @@
+package org.spongycastle.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.spongycastle.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;
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CRLHolder.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CRLHolder.java
new file mode 100644
index 00000000..91bcd88d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CRLHolder.java
@@ -0,0 +1,26 @@
+package org.spongycastle.cert.jcajce;
+
+import java.security.cert.CRLException;
+import java.security.cert.X509CRL;
+
+import org.spongycastle.asn1.x509.CertificateList;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CertificateConverter.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CertificateConverter.java
new file mode 100644
index 00000000..5e46a17d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CertificateConverter.java
@@ -0,0 +1,116 @@
+package org.spongycastle.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.spongycastle.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;
+ }
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CertificateHolder.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CertificateHolder.java
new file mode 100644
index 00000000..a523f975
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509CertificateHolder.java
@@ -0,0 +1,26 @@
+package org.spongycastle.cert.jcajce;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509ContentVerifierProviderBuilder.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509ContentVerifierProviderBuilder.java
new file mode 100644
index 00000000..46eb3b43
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509ContentVerifierProviderBuilder.java
@@ -0,0 +1,50 @@
+package org.spongycastle.cert.jcajce;
+
+import java.security.Provider;
+import java.security.cert.CertificateException;
+
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.X509ContentVerifierProviderBuilder;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
+
+public class JcaX509ContentVerifierProviderBuilder
+ implements X509ContentVerifierProviderBuilder
+{
+ private JcaContentVerifierProviderBuilder builder = new JcaContentVerifierProviderBuilder();
+
+ public JcaX509ContentVerifierProviderBuilder setProvider(Provider provider)
+ {
+ this.builder.setProvider(provider);
+
+ return this;
+ }
+
+ public JcaX509ContentVerifierProviderBuilder setProvider(String providerName)
+ {
+ this.builder.setProvider(providerName);
+
+ return this;
+ }
+
+ public ContentVerifierProvider build(SubjectPublicKeyInfo validatingKeyInfo)
+ throws OperatorCreationException
+ {
+ return builder.build(validatingKeyInfo);
+ }
+
+ public ContentVerifierProvider build(X509CertificateHolder validatingKeyInfo)
+ throws OperatorCreationException
+ {
+ try
+ {
+ return builder.build(validatingKeyInfo);
+ }
+ catch (CertificateException e)
+ {
+ throw new OperatorCreationException("Unable to process certificate: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java
new file mode 100644
index 00000000..b601e24e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java
@@ -0,0 +1,145 @@
+package org.spongycastle.cert.jcajce;
+
+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.PublicKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.X509ExtensionUtils;
+import org.spongycastle.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()));
+ }
+
+ public AuthorityKeyIdentifier createAuthorityKeyIdentifier(PublicKey pubKey, X500Principal name, BigInteger serial)
+ {
+ return super.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), new GeneralNames(new GeneralName(X500Name.getInstance(name.getEncoded()))), serial);
+ }
+
+ public AuthorityKeyIdentifier createAuthorityKeyIdentifier(PublicKey pubKey, GeneralNames generalNames, BigInteger serial)
+ {
+ return super.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), generalNames, serial);
+ }
+
+ /**
+ * Return a RFC 3280 type 1 key identifier. As in:
+ * <pre>
+ * (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).
+ * </pre>
+ * @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:
+ * <pre>
+ * (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.
+ * </pre>
+ * @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;
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java
new file mode 100644
index 00000000..e5e4f83d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java
@@ -0,0 +1,48 @@
+package org.spongycastle.cert.jcajce;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.util.Date;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java
new file mode 100644
index 00000000..97d544bd
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java
@@ -0,0 +1,23 @@
+package org.spongycastle.cert.jcajce;
+
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java
new file mode 100644
index 00000000..238edbe8
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java
@@ -0,0 +1,119 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x509.Time;
+import org.spongycastle.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 a PublicKey.
+ *
+ * @param issuer X500Name representing the issuer of this certificate.
+ * @param serial the serial number for the certificate.
+ * @param notBefore Time before which the certificate is not valid.
+ * @param notAfter Time 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, Time notBefore, Time 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/NamedCertHelper.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/NamedCertHelper.java
new file mode 100644
index 00000000..89584138
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/NamedCertHelper.java
@@ -0,0 +1,22 @@
+package org.spongycastle.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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/jcajce/ProviderCertHelper.java b/pkix/src/main/java/org/spongycastle/cert/jcajce/ProviderCertHelper.java
new file mode 100644
index 00000000..ffe37e9b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/jcajce/ProviderCertHelper.java
@@ -0,0 +1,22 @@
+package org.spongycastle.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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/BasicOCSPResp.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/BasicOCSPResp.java
new file mode 100644
index 00000000..f3c65670
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/BasicOCSPResp.java
@@ -0,0 +1,212 @@
+package org.spongycastle.cert.ocsp;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ocsp.BasicOCSPResponse;
+import org.spongycastle.asn1.ocsp.ResponseData;
+import org.spongycastle.asn1.ocsp.SingleResponse;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.operator.ContentVerifierProvider;
+
+/**
+ * <pre>
+ * BasicOCSPResponse ::= SEQUENCE {
+ * tbsResponseData ResponseData,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING,
+ * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ * </pre>
+ */
+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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/BasicOCSPRespBuilder.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/BasicOCSPRespBuilder.java
new file mode 100644
index 00000000..ac759de6
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/BasicOCSPRespBuilder.java
@@ -0,0 +1,264 @@
+package org.spongycastle.cert.ocsp;
+
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.DERGeneralizedTime;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.ocsp.BasicOCSPResponse;
+import org.spongycastle.asn1.ocsp.CertStatus;
+import org.spongycastle.asn1.ocsp.ResponseData;
+import org.spongycastle.asn1.ocsp.RevokedInfo;
+import org.spongycastle.asn1.ocsp.SingleResponse;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.CRLReason;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.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;
+ ASN1GeneralizedTime thisUpdate;
+ ASN1GeneralizedTime 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));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/CertificateID.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/CertificateID.java
new file mode 100644
index 00000000..aac029ca
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/CertificateID.java
@@ -0,0 +1,156 @@
+package org.spongycastle.cert.ocsp;
+
+import java.io.OutputStream;
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.ocsp.CertID;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/CertificateStatus.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/CertificateStatus.java
new file mode 100644
index 00000000..ba84b8f8
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/CertificateStatus.java
@@ -0,0 +1,6 @@
+package org.spongycastle.cert.ocsp;
+
+public interface CertificateStatus
+{
+ public static final CertificateStatus GOOD = null;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPException.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPException.java
new file mode 100644
index 00000000..be91e3d8
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPException.java
@@ -0,0 +1,27 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPReq.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPReq.java
new file mode 100644
index 00000000..17089673
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPReq.java
@@ -0,0 +1,259 @@
+package org.spongycastle.cert.ocsp;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Set;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1Exception;
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OutputStream;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ocsp.OCSPRequest;
+import org.spongycastle.asn1.ocsp.Request;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.cert.CertIOException;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.operator.ContentVerifierProvider;
+
+/**
+ * <pre>
+ * 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 }
+ * </pre>
+ */
+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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPReqBuilder.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPReqBuilder.java
new file mode 100644
index 00000000..2bc0a6d1
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPReqBuilder.java
@@ -0,0 +1,199 @@
+package org.spongycastle.cert.ocsp;
+
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.ocsp.OCSPRequest;
+import org.spongycastle.asn1.ocsp.Request;
+import org.spongycastle.asn1.ocsp.Signature;
+import org.spongycastle.asn1.ocsp.TBSRequest;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.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.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPResp.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPResp.java
new file mode 100644
index 00000000..0b587f70
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPResp.java
@@ -0,0 +1,141 @@
+package org.spongycastle.cert.ocsp;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1Exception;
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ocsp.BasicOCSPResponse;
+import org.spongycastle.asn1.ocsp.OCSPObjectIdentifiers;
+import org.spongycastle.asn1.ocsp.OCSPResponse;
+import org.spongycastle.asn1.ocsp.ResponseBytes;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPRespBuilder.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPRespBuilder.java
new file mode 100644
index 00000000..fe2da11d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPRespBuilder.java
@@ -0,0 +1,59 @@
+package org.spongycastle.cert.ocsp;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.ocsp.OCSPObjectIdentifiers;
+import org.spongycastle.asn1.ocsp.OCSPResponse;
+import org.spongycastle.asn1.ocsp.OCSPResponseStatus;
+import org.spongycastle.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");
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPUtils.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPUtils.java
new file mode 100644
index 00000000..a58ca071
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/OCSPUtils.java
@@ -0,0 +1,64 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/Req.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/Req.java
new file mode 100644
index 00000000..52c174dd
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/Req.java
@@ -0,0 +1,25 @@
+package org.spongycastle.cert.ocsp;
+
+import org.spongycastle.asn1.ocsp.Request;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/RespData.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/RespData.java
new file mode 100644
index 00000000..3db55a3e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/RespData.java
@@ -0,0 +1,52 @@
+package org.spongycastle.cert.ocsp;
+
+import java.util.Date;
+
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ocsp.ResponseData;
+import org.spongycastle.asn1.ocsp.SingleResponse;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/RespID.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/RespID.java
new file mode 100644
index 00000000..7510200d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/RespID.java
@@ -0,0 +1,89 @@
+package org.spongycastle.cert.ocsp;
+
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.ocsp.ResponderID;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/RevokedStatus.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/RevokedStatus.java
new file mode 100644
index 00000000..0842ea58
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/RevokedStatus.java
@@ -0,0 +1,55 @@
+package org.spongycastle.cert.ocsp;
+
+import java.util.Date;
+
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.ocsp.RevokedInfo;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/SingleResp.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/SingleResp.java
new file mode 100644
index 00000000..98beb8b3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/SingleResp.java
@@ -0,0 +1,102 @@
+package org.spongycastle.cert.ocsp;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ocsp.CertStatus;
+import org.spongycastle.asn1.ocsp.RevokedInfo;
+import org.spongycastle.asn1.ocsp.SingleResponse;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/UnknownStatus.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/UnknownStatus.java
new file mode 100644
index 00000000..42eda721
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/UnknownStatus.java
@@ -0,0 +1,12 @@
+package org.spongycastle.cert.ocsp;
+
+/**
+ * wrapper for the UnknownInfo object
+ */
+public class UnknownStatus
+ implements CertificateStatus
+{
+ public UnknownStatus()
+ {
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java
new file mode 100644
index 00000000..cbd591db
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/jcajce/JcaBasicOCSPRespBuilder.java
@@ -0,0 +1,18 @@
+package org.spongycastle.cert.ocsp.jcajce;
+
+import java.security.PublicKey;
+
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.ocsp.BasicOCSPRespBuilder;
+import org.spongycastle.cert.ocsp.OCSPException;
+import org.spongycastle.operator.DigestCalculator;
+
+public class JcaBasicOCSPRespBuilder
+ extends BasicOCSPRespBuilder
+{
+ public JcaBasicOCSPRespBuilder(PublicKey key, DigestCalculator digCalc)
+ throws OCSPException
+ {
+ super(SubjectPublicKeyInfo.getInstance(key.getEncoded()), digCalc);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/jcajce/JcaCertificateID.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/jcajce/JcaCertificateID.java
new file mode 100644
index 00000000..d59e7e04
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/jcajce/JcaCertificateID.java
@@ -0,0 +1,20 @@
+package org.spongycastle.cert.ocsp.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.spongycastle.cert.ocsp.CertificateID;
+import org.spongycastle.cert.ocsp.OCSPException;
+import org.spongycastle.operator.DigestCalculator;
+
+public class JcaCertificateID
+ extends CertificateID
+{
+ public JcaCertificateID(DigestCalculator digestCalculator, X509Certificate issuerCert, BigInteger number)
+ throws OCSPException, CertificateEncodingException
+ {
+ super(digestCalculator, new JcaX509CertificateHolder(issuerCert), number);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java b/pkix/src/main/java/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java
new file mode 100644
index 00000000..55a390be
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java
@@ -0,0 +1,26 @@
+package org.spongycastle.cert.ocsp.jcajce;
+
+import java.security.PublicKey;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.ocsp.OCSPException;
+import org.spongycastle.cert.ocsp.RespID;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/CertPath.java b/pkix/src/main/java/org/spongycastle/cert/path/CertPath.java
new file mode 100644
index 00000000..bbb20a4d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/CertPath.java
@@ -0,0 +1,80 @@
+package org.spongycastle.cert.path;
+
+import org.spongycastle.cert.X509CertificateHolder;
+
+public class CertPath
+{
+ private final X509CertificateHolder[] certificates;
+
+ public CertPath(X509CertificateHolder[] certificates)
+ {
+ this.certificates = copyArray(certificates);
+ }
+
+ public X509CertificateHolder[] getCertificates()
+ {
+ return copyArray(certificates);
+ }
+
+ public CertPathValidationResult validate(CertPathValidation[] ruleSet)
+ {
+ CertPathValidationContext context = new CertPathValidationContext(CertPathUtils.getCriticalExtensionsOIDs(certificates));
+
+ for (int i = 0; i != ruleSet.length; i++)
+ {
+ for (int j = certificates.length - 1; j >= 0; j--)
+ {
+ try
+ {
+ context.setIsEndEntity(j == 0);
+ ruleSet[i].validate(context, certificates[j]);
+ }
+ catch (CertPathValidationException e)
+ { // TODO: introduce object to hold (i and e)
+ return new CertPathValidationResult(context, j, i, e);
+ }
+ }
+ }
+
+ return new CertPathValidationResult(context);
+ }
+
+ public CertPathValidationResult evaluate(CertPathValidation[] ruleSet)
+ {
+ CertPathValidationContext context = new CertPathValidationContext(CertPathUtils.getCriticalExtensionsOIDs(certificates));
+
+ CertPathValidationResultBuilder builder = new CertPathValidationResultBuilder();
+
+ for (int i = 0; i != ruleSet.length; i++)
+ {
+ for (int j = certificates.length - 1; j >= 0; j--)
+ {
+ try
+ {
+ context.setIsEndEntity(j == 0);
+ ruleSet[i].validate(context, certificates[j]);
+ }
+ catch (CertPathValidationException e)
+ {
+ builder.addException(e);
+ }
+ }
+ }
+
+ return builder.build();
+ }
+
+ private X509CertificateHolder[] copyArray(X509CertificateHolder[] array)
+ {
+ X509CertificateHolder[] rv = new X509CertificateHolder[array.length];
+
+ System.arraycopy(array, 0, rv, 0, rv.length);
+
+ return rv;
+ }
+
+ public int length()
+ {
+ return certificates.length;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/CertPathUtils.java b/pkix/src/main/java/org/spongycastle/cert/path/CertPathUtils.java
new file mode 100644
index 00000000..257e0bb8
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/CertPathUtils.java
@@ -0,0 +1,21 @@
+package org.spongycastle.cert.path;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.spongycastle.cert.X509CertificateHolder;
+
+class CertPathUtils
+{
+ static Set getCriticalExtensionsOIDs(X509CertificateHolder[] certificates)
+ {
+ Set criticalExtensions = new HashSet();
+
+ for (int i = 0; i != certificates.length; i++)
+ {
+ criticalExtensions.addAll(certificates[i].getCriticalExtensionOIDs());
+ }
+
+ return criticalExtensions;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidation.java b/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidation.java
new file mode 100644
index 00000000..11f48367
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidation.java
@@ -0,0 +1,11 @@
+package org.spongycastle.cert.path;
+
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.util.Memoable;
+
+public interface CertPathValidation
+ extends Memoable
+{
+ public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
+ throws CertPathValidationException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationContext.java b/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationContext.java
new file mode 100644
index 00000000..010b4ef6
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationContext.java
@@ -0,0 +1,61 @@
+package org.spongycastle.cert.path;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.util.Memoable;
+
+public class CertPathValidationContext
+ implements Memoable
+{
+ private Set criticalExtensions;
+
+ private Set handledExtensions = new HashSet();
+ private boolean endEntity;
+ private int index;
+
+ public CertPathValidationContext(Set criticalExtensionsOIDs)
+ {
+ this.criticalExtensions = criticalExtensionsOIDs;
+ }
+
+ public void addHandledExtension(ASN1ObjectIdentifier extensionIdentifier)
+ {
+ this.handledExtensions.add(extensionIdentifier);
+ }
+
+ public void setIsEndEntity(boolean isEndEntity)
+ {
+ this.endEntity = isEndEntity;
+ }
+
+ public Set getUnhandledCriticalExtensionOIDs()
+ {
+ Set rv = new HashSet(criticalExtensions);
+
+ rv.removeAll(handledExtensions);
+
+ return rv;
+ }
+
+ /**
+ * Returns true if the current certificate is the end-entity certificate.
+ *
+ * @return if current cert end-entity, false otherwise.
+ */
+ public boolean isEndEntity()
+ {
+ return endEntity;
+ }
+
+ public Memoable copy()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void reset(Memoable other)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationException.java b/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationException.java
new file mode 100644
index 00000000..0a1188d1
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationException.java
@@ -0,0 +1,24 @@
+package org.spongycastle.cert.path;
+
+public class CertPathValidationException
+ extends Exception
+{
+ private final Exception cause;
+
+ public CertPathValidationException(String msg)
+ {
+ this(msg, null);
+ }
+
+ public CertPathValidationException(String msg, Exception cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationResult.java b/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationResult.java
new file mode 100644
index 00000000..276ef8d4
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationResult.java
@@ -0,0 +1,66 @@
+package org.spongycastle.cert.path;
+
+import java.util.Collections;
+import java.util.Set;
+
+public class CertPathValidationResult
+{
+ private final boolean isValid;
+ private final CertPathValidationException cause;
+ private final Set unhandledCriticalExtensionOIDs;
+
+ private int[] certIndexes;
+
+ public CertPathValidationResult(CertPathValidationContext context)
+ {
+ this.unhandledCriticalExtensionOIDs = Collections.unmodifiableSet(context.getUnhandledCriticalExtensionOIDs());
+ this.isValid = this.unhandledCriticalExtensionOIDs.isEmpty();
+ cause = null;
+ }
+
+ public CertPathValidationResult(CertPathValidationContext context, int certIndex, int ruleIndex, CertPathValidationException cause)
+ {
+ this.unhandledCriticalExtensionOIDs = Collections.unmodifiableSet(context.getUnhandledCriticalExtensionOIDs());
+ this.isValid = false;
+ this.cause = cause;
+ }
+
+ public CertPathValidationResult(CertPathValidationContext context, int[] certIndexes, int[] ruleIndexes, CertPathValidationException[] cause)
+ {
+ // TODO
+ this.unhandledCriticalExtensionOIDs = Collections.unmodifiableSet(context.getUnhandledCriticalExtensionOIDs());
+ this.isValid = false;
+ this.cause = cause[0];
+ this.certIndexes = certIndexes;
+ }
+
+ public boolean isValid()
+ {
+ return isValid;
+ }
+
+ public Exception getCause()
+ {
+ if (cause != null)
+ {
+ return cause;
+ }
+
+ if (!unhandledCriticalExtensionOIDs.isEmpty())
+ {
+ return new CertPathValidationException("Unhandled Critical Extensions");
+ }
+
+ return null;
+ }
+
+ public Set getUnhandledCriticalExtensionOIDs()
+ {
+ return unhandledCriticalExtensionOIDs;
+ }
+
+ public boolean isDetailed()
+ {
+ return this.certIndexes != null;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationResultBuilder.java b/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationResultBuilder.java
new file mode 100644
index 00000000..80bf7ff2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/CertPathValidationResultBuilder.java
@@ -0,0 +1,14 @@
+package org.spongycastle.cert.path;
+
+class CertPathValidationResultBuilder
+{
+ public CertPathValidationResult build()
+ {
+ return new CertPathValidationResult(null, 0, 0, null);
+ }
+
+ public void addException(CertPathValidationException exception)
+ {
+ //To change body of created methods use File | Settings | File Templates.
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/validations/BasicConstraintsValidation.java b/pkix/src/main/java/org/spongycastle/cert/path/validations/BasicConstraintsValidation.java
new file mode 100644
index 00000000..bfe0f1a4
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/validations/BasicConstraintsValidation.java
@@ -0,0 +1,103 @@
+package org.spongycastle.cert.path.validations;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.x509.BasicConstraints;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.path.CertPathValidation;
+import org.spongycastle.cert.path.CertPathValidationContext;
+import org.spongycastle.cert.path.CertPathValidationException;
+import org.spongycastle.util.Memoable;
+
+public class BasicConstraintsValidation
+ implements CertPathValidation
+{
+ private boolean isMandatory;
+ private BasicConstraints bc;
+ private int maxPathLength;
+
+ public BasicConstraintsValidation()
+ {
+ this(true);
+ }
+
+ public BasicConstraintsValidation(boolean isMandatory)
+ {
+ this.isMandatory = isMandatory;
+ }
+
+ public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
+ throws CertPathValidationException
+ {
+ if (maxPathLength < 0)
+ {
+ throw new CertPathValidationException("BasicConstraints path length exceeded");
+ }
+
+ context.addHandledExtension(Extension.basicConstraints);
+
+ BasicConstraints certBC = BasicConstraints.fromExtensions(certificate.getExtensions());
+
+ if (certBC != null)
+ {
+ if (bc != null)
+ {
+ if (certBC.isCA())
+ {
+ BigInteger pathLengthConstraint = certBC.getPathLenConstraint();
+
+ if (pathLengthConstraint != null)
+ {
+ int plc = pathLengthConstraint.intValue();
+
+ if (plc < maxPathLength)
+ {
+ maxPathLength = plc;
+ bc = certBC;
+ }
+ }
+ }
+ }
+ else
+ {
+ bc = certBC;
+ if (certBC.isCA())
+ {
+ maxPathLength = certBC.getPathLenConstraint().intValue();
+ }
+ }
+ }
+ else
+ {
+ if (bc != null)
+ {
+ maxPathLength--;
+ }
+ }
+
+ if (isMandatory && bc == null)
+ {
+ throw new CertPathValidationException("BasicConstraints not present in path");
+ }
+ }
+
+ public Memoable copy()
+ {
+ BasicConstraintsValidation v = new BasicConstraintsValidation(isMandatory);
+
+ v.bc = this.bc;
+ v.maxPathLength = this.maxPathLength;
+
+ return v;
+ }
+
+ public void reset(Memoable other)
+ {
+ BasicConstraintsValidation v = (BasicConstraintsValidation)other;
+
+ this.isMandatory = v.isMandatory;
+ this.bc = v.bc;
+ this.maxPathLength = v.maxPathLength;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/validations/CRLValidation.java b/pkix/src/main/java/org/spongycastle/cert/path/validations/CRLValidation.java
new file mode 100644
index 00000000..325126e1
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/validations/CRLValidation.java
@@ -0,0 +1,78 @@
+package org.spongycastle.cert.path.validations;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.path.CertPathValidation;
+import org.spongycastle.cert.path.CertPathValidationContext;
+import org.spongycastle.cert.path.CertPathValidationException;
+import org.spongycastle.util.Memoable;
+import org.spongycastle.util.Selector;
+import org.spongycastle.util.Store;
+
+public class CRLValidation
+ implements CertPathValidation
+{
+ private Store crls;
+ private X500Name workingIssuerName;
+
+ public CRLValidation(X500Name trustAnchorName, Store crls)
+ {
+ this.workingIssuerName = trustAnchorName;
+ this.crls = crls;
+ }
+
+ public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
+ throws CertPathValidationException
+ {
+ // TODO: add handling of delta CRLs
+ Collection matches = crls.getMatches(new Selector()
+ {
+ public boolean match(Object obj)
+ {
+ X509CRLHolder crl = (X509CRLHolder)obj;
+
+ return (crl.getIssuer().equals(workingIssuerName));
+ }
+
+ public Object clone()
+ {
+ return this;
+ }
+ });
+
+ if (matches.isEmpty())
+ {
+ throw new CertPathValidationException("CRL for " + workingIssuerName + " not found");
+ }
+
+ for (Iterator it = matches.iterator(); it.hasNext();)
+ {
+ X509CRLHolder crl = (X509CRLHolder)it.next();
+
+ // TODO: not quite right!
+ if (crl.getRevokedCertificate(certificate.getSerialNumber()) != null)
+ {
+ throw new CertPathValidationException("Certificate revoked");
+ }
+ }
+
+ this.workingIssuerName = certificate.getSubject();
+ }
+
+ public Memoable copy()
+ {
+ return new CRLValidation(workingIssuerName, crls);
+ }
+
+ public void reset(Memoable other)
+ {
+ CRLValidation v = (CRLValidation)other;
+
+ this.workingIssuerName = v.workingIssuerName;
+ this.crls = v.crls;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/validations/CertificatePoliciesValidation.java b/pkix/src/main/java/org/spongycastle/cert/path/validations/CertificatePoliciesValidation.java
new file mode 100644
index 00000000..7015adb0
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/validations/CertificatePoliciesValidation.java
@@ -0,0 +1,146 @@
+package org.spongycastle.cert.path.validations;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.PolicyConstraints;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.path.CertPathValidation;
+import org.spongycastle.cert.path.CertPathValidationContext;
+import org.spongycastle.cert.path.CertPathValidationException;
+import org.spongycastle.util.Memoable;
+
+public class CertificatePoliciesValidation
+ implements CertPathValidation
+{
+ private int explicitPolicy;
+ private int policyMapping;
+ private int inhibitAnyPolicy;
+
+ CertificatePoliciesValidation(int pathLength)
+ {
+ this(pathLength, false, false, false);
+ }
+
+ CertificatePoliciesValidation(int pathLength, boolean isExplicitPolicyRequired, boolean isAnyPolicyInhibited, boolean isPolicyMappingInhibited)
+ {
+ //
+ // (d)
+ //
+
+ if (isExplicitPolicyRequired)
+ {
+ explicitPolicy = 0;
+ }
+ else
+ {
+ explicitPolicy = pathLength + 1;
+ }
+
+ //
+ // (e)
+ //
+ if (isAnyPolicyInhibited)
+ {
+ inhibitAnyPolicy = 0;
+ }
+ else
+ {
+ inhibitAnyPolicy = pathLength + 1;
+ }
+
+ //
+ // (f)
+ //
+ if (isPolicyMappingInhibited)
+ {
+ policyMapping = 0;
+ }
+ else
+ {
+ policyMapping = pathLength + 1;
+ }
+ }
+
+ public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
+ throws CertPathValidationException
+ {
+ context.addHandledExtension(Extension.policyConstraints);
+ context.addHandledExtension(Extension.inhibitAnyPolicy);
+
+ if (!context.isEndEntity())
+ {
+ if (!ValidationUtils.isSelfIssued(certificate))
+ {
+ //
+ // H (1), (2), (3)
+ //
+ explicitPolicy = countDown(explicitPolicy);
+ policyMapping = countDown(policyMapping);
+ inhibitAnyPolicy = countDown(inhibitAnyPolicy);
+
+ //
+ // I (1), (2)
+ //
+ PolicyConstraints policyConstraints = PolicyConstraints.fromExtensions(certificate.getExtensions());
+
+ if (policyConstraints != null)
+ {
+ BigInteger requireExplicitPolicyMapping = policyConstraints.getRequireExplicitPolicyMapping();
+ if (requireExplicitPolicyMapping != null)
+ {
+ if (requireExplicitPolicyMapping.intValue() < explicitPolicy)
+ {
+ explicitPolicy = requireExplicitPolicyMapping.intValue();
+ }
+ }
+
+ BigInteger inhibitPolicyMapping = policyConstraints.getInhibitPolicyMapping();
+ if (inhibitPolicyMapping != null)
+ {
+ if (inhibitPolicyMapping.intValue() < policyMapping)
+ {
+ policyMapping = inhibitPolicyMapping.intValue();
+ }
+ }
+ }
+
+ //
+ // J
+ //
+ Extension ext = certificate.getExtension(Extension.inhibitAnyPolicy);
+
+ if (ext != null)
+ {
+ int extValue = ASN1Integer.getInstance(ext.getParsedValue()).getValue().intValue();
+
+ if (extValue < inhibitAnyPolicy)
+ {
+ inhibitAnyPolicy = extValue;
+ }
+ }
+ }
+ }
+ }
+
+ private int countDown(int policyCounter)
+ {
+ if (policyCounter != 0)
+ {
+ return policyCounter - 1;
+ }
+
+ return 0;
+ }
+
+ public Memoable copy()
+ {
+ return new CertificatePoliciesValidation(0); // TODO:
+ }
+
+ public void reset(Memoable other)
+ {
+ CertificatePoliciesValidation v = (CertificatePoliciesValidation)other; // TODO:
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/validations/CertificatePoliciesValidationBuilder.java b/pkix/src/main/java/org/spongycastle/cert/path/validations/CertificatePoliciesValidationBuilder.java
new file mode 100644
index 00000000..44817b61
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/validations/CertificatePoliciesValidationBuilder.java
@@ -0,0 +1,35 @@
+package org.spongycastle.cert.path.validations;
+
+import org.spongycastle.cert.path.CertPath;
+
+public class CertificatePoliciesValidationBuilder
+{
+ private boolean isExplicitPolicyRequired;
+ private boolean isAnyPolicyInhibited;
+ private boolean isPolicyMappingInhibited;
+
+ public void setAnyPolicyInhibited(boolean anyPolicyInhibited)
+ {
+ isAnyPolicyInhibited = anyPolicyInhibited;
+ }
+
+ public void setExplicitPolicyRequired(boolean explicitPolicyRequired)
+ {
+ isExplicitPolicyRequired = explicitPolicyRequired;
+ }
+
+ public void setPolicyMappingInhibited(boolean policyMappingInhibited)
+ {
+ isPolicyMappingInhibited = policyMappingInhibited;
+ }
+
+ public CertificatePoliciesValidation build(int pathLen)
+ {
+ return new CertificatePoliciesValidation(pathLen, isExplicitPolicyRequired, isAnyPolicyInhibited, isPolicyMappingInhibited);
+ }
+
+ public CertificatePoliciesValidation build(CertPath path)
+ {
+ return build(path.length());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/validations/KeyUsageValidation.java b/pkix/src/main/java/org/spongycastle/cert/path/validations/KeyUsageValidation.java
new file mode 100644
index 00000000..7211b7cd
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/validations/KeyUsageValidation.java
@@ -0,0 +1,63 @@
+package org.spongycastle.cert.path.validations;
+
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.KeyUsage;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.path.CertPathValidation;
+import org.spongycastle.cert.path.CertPathValidationContext;
+import org.spongycastle.cert.path.CertPathValidationException;
+import org.spongycastle.util.Memoable;
+
+public class KeyUsageValidation
+ implements CertPathValidation
+{
+ private boolean isMandatory;
+
+ public KeyUsageValidation()
+ {
+ this(true);
+ }
+
+ public KeyUsageValidation(boolean isMandatory)
+ {
+ this.isMandatory = isMandatory;
+ }
+
+ public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
+ throws CertPathValidationException
+ {
+ context.addHandledExtension(Extension.keyUsage);
+
+ if (!context.isEndEntity())
+ {
+ KeyUsage usage = KeyUsage.fromExtensions(certificate.getExtensions());
+
+ if (usage != null)
+ {
+ if (!usage.hasUsages(KeyUsage.keyCertSign))
+ {
+ throw new CertPathValidationException("Issuer certificate KeyUsage extension does not permit key signing");
+ }
+ }
+ else
+ {
+ if (isMandatory)
+ {
+ throw new CertPathValidationException("KeyUsage extension not present in CA certificate");
+ }
+ }
+ }
+ }
+
+ public Memoable copy()
+ {
+ return new KeyUsageValidation(isMandatory);
+ }
+
+ public void reset(Memoable other)
+ {
+ KeyUsageValidation v = (KeyUsageValidation)other;
+
+ this.isMandatory = v.isMandatory;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/validations/ParentCertIssuedValidation.java b/pkix/src/main/java/org/spongycastle/cert/path/validations/ParentCertIssuedValidation.java
new file mode 100644
index 00000000..dff47fb7
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/validations/ParentCertIssuedValidation.java
@@ -0,0 +1,127 @@
+package org.spongycastle.cert.path.validations;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Null;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.CertException;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.X509ContentVerifierProviderBuilder;
+import org.spongycastle.cert.path.CertPathValidation;
+import org.spongycastle.cert.path.CertPathValidationContext;
+import org.spongycastle.cert.path.CertPathValidationException;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.util.Memoable;
+
+public class ParentCertIssuedValidation
+ implements CertPathValidation
+{
+ private X509ContentVerifierProviderBuilder contentVerifierProvider;
+
+ private X500Name workingIssuerName;
+ private SubjectPublicKeyInfo workingPublicKey;
+ private AlgorithmIdentifier workingAlgId;
+
+ public ParentCertIssuedValidation(X509ContentVerifierProviderBuilder contentVerifierProvider)
+ {
+ this.contentVerifierProvider = contentVerifierProvider;
+ }
+
+ public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
+ throws CertPathValidationException
+ {
+ if (workingIssuerName != null)
+ {
+ if (!workingIssuerName.equals(certificate.getIssuer()))
+ {
+ throw new CertPathValidationException("Certificate issue does not match parent");
+ }
+ }
+
+ if (workingPublicKey != null)
+ {
+ try
+ {
+ SubjectPublicKeyInfo validatingKeyInfo;
+
+ if (workingPublicKey.getAlgorithm().equals(workingAlgId))
+ {
+ validatingKeyInfo = workingPublicKey;
+ }
+ else
+ {
+ validatingKeyInfo = new SubjectPublicKeyInfo(workingAlgId, workingPublicKey.parsePublicKey());
+ }
+
+ if (!certificate.isSignatureValid(contentVerifierProvider.build(validatingKeyInfo)))
+ {
+ throw new CertPathValidationException("Certificate signature not for public key in parent");
+ }
+ }
+ catch (OperatorCreationException e)
+ {
+ throw new CertPathValidationException("Unable to create verifier: " + e.getMessage(), e);
+ }
+ catch (CertException e)
+ {
+ throw new CertPathValidationException("Unable to validate signature: " + e.getMessage(), e);
+ }
+ catch (IOException e)
+ {
+ throw new CertPathValidationException("Unable to build public key: " + e.getMessage(), e);
+ }
+ }
+
+ workingIssuerName = certificate.getSubject();
+ workingPublicKey = certificate.getSubjectPublicKeyInfo();
+
+ if (workingAlgId != null)
+ {
+ // check for inherited parameters
+ if (workingPublicKey.getAlgorithm().getAlgorithm().equals(workingAlgId.getAlgorithm()))
+ {
+ if (!isNull(workingPublicKey.getAlgorithm().getParameters()))
+ {
+ workingAlgId = workingPublicKey.getAlgorithm();
+ }
+ }
+ else
+ {
+ workingAlgId = workingPublicKey.getAlgorithm();
+ }
+ }
+ else
+ {
+ workingAlgId = workingPublicKey.getAlgorithm();
+ }
+ }
+
+ private boolean isNull(ASN1Encodable obj)
+ {
+ return obj == null || obj instanceof ASN1Null;
+ }
+
+ public Memoable copy()
+ {
+ ParentCertIssuedValidation v = new ParentCertIssuedValidation(contentVerifierProvider);
+
+ v.workingAlgId = this.workingAlgId;
+ v.workingIssuerName = this.workingIssuerName;
+ v.workingPublicKey = this.workingPublicKey;
+
+ return v;
+ }
+
+ public void reset(Memoable other)
+ {
+ ParentCertIssuedValidation v = (ParentCertIssuedValidation)other;
+
+ this.contentVerifierProvider = v.contentVerifierProvider;
+ this.workingAlgId = v.workingAlgId;
+ this.workingIssuerName = v.workingIssuerName;
+ this.workingPublicKey = v.workingPublicKey;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/path/validations/ValidationUtils.java b/pkix/src/main/java/org/spongycastle/cert/path/validations/ValidationUtils.java
new file mode 100644
index 00000000..5dbf495a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/path/validations/ValidationUtils.java
@@ -0,0 +1,11 @@
+package org.spongycastle.cert.path.validations;
+
+import org.spongycastle.cert.X509CertificateHolder;
+
+class ValidationUtils
+{
+ static boolean isSelfIssued(X509CertificateHolder cert)
+ {
+ return cert.getSubject().equals(cert.getIssuer());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/selector/MSOutlookKeyIdCalculator.java b/pkix/src/main/java/org/spongycastle/cert/selector/MSOutlookKeyIdCalculator.java
new file mode 100644
index 00000000..23748ac3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/selector/MSOutlookKeyIdCalculator.java
@@ -0,0 +1,422 @@
+package org.spongycastle.cert.selector;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.util.Pack;
+
+class MSOutlookKeyIdCalculator
+{
+ // This is less than ideal, but it seems to be the best way of supporting this without exposing SHA-1
+ // as the class is only used to workout the MSOutlook Key ID, you can think of the fact it's SHA-1 as
+ // a coincidence...
+ static byte[] calculateKeyId(SubjectPublicKeyInfo info)
+ {
+ SHA1Digest dig = new SHA1Digest();
+ byte[] hash = new byte[dig.getDigestSize()];
+ byte[] spkiEnc = new byte[0];
+ try
+ {
+ spkiEnc = info.getEncoded(ASN1Encoding.DER);
+ }
+ catch (IOException e)
+ {
+ return new byte[0];
+ }
+
+ // try the outlook 2010 calculation
+ dig.update(spkiEnc, 0, spkiEnc.length);
+
+ dig.doFinal(hash, 0);
+
+ return hash;
+ }
+
+ private static abstract class GeneralDigest
+ {
+ 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;
+ }
+ }
+
+ protected abstract void processWord(byte[] in, int inOff);
+
+ protected abstract void processLength(long bitLength);
+
+ protected abstract void processBlock();
+ }
+
+ private static 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();
+ }
+
+ 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;
+ }
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/selector/X509AttributeCertificateHolderSelector.java b/pkix/src/main/java/org/spongycastle/cert/selector/X509AttributeCertificateHolderSelector.java
new file mode 100644
index 00000000..3ae30b33
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/selector/X509AttributeCertificateHolderSelector.java
@@ -0,0 +1,268 @@
+package org.spongycastle.cert.selector;
+
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.Date;
+
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.Target;
+import org.spongycastle.asn1.x509.TargetInformation;
+import org.spongycastle.asn1.x509.Targets;
+import org.spongycastle.cert.AttributeCertificateHolder;
+import org.spongycastle.cert.AttributeCertificateIssuer;
+import org.spongycastle.cert.X509AttributeCertificateHolder;
+import org.spongycastle.util.Selector;
+
+/**
+ * This class is an <code>Selector</code> 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 <code>true</code> if the attribute certificate is a match
+ * <code>false</code> 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<targetss.length; i++)
+ {
+ Targets t = targetss[i];
+ Target[] targets = t.getTargets();
+ for (int j=0; j<targets.length; j++)
+ {
+ if (targetNames.contains(GeneralName.getInstance(targets[j]
+ .getTargetName())))
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found)
+ {
+ return false;
+ }
+ }
+ if (!targetGroups.isEmpty())
+ {
+ boolean found = false;
+
+ for (int i=0; i<targetss.length; i++)
+ {
+ Targets t = targetss[i];
+ Target[] targets = t.getTargets();
+ for (int j=0; j<targets.length; j++)
+ {
+ if (targetGroups.contains(GeneralName.getInstance(targets[j]
+ .getTargetGroup())))
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found)
+ {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns a clone of this object.
+ *
+ * @return the clone.
+ */
+ public Object clone()
+ {
+ X509AttributeCertificateHolderSelector sel = new X509AttributeCertificateHolderSelector(
+ holder, issuer, serialNumber, attributeCertificateValid, attributeCert, targetNames, targetGroups);
+
+ return sel;
+ }
+
+ /**
+ * Returns the attribute certificate holder which must be matched.
+ *
+ * @return Returns an X509AttributeCertificateHolder
+ */
+ public X509AttributeCertificateHolder getAttributeCert()
+ {
+ return attributeCert;
+ }
+
+ /**
+ * Get the criteria for the validity.
+ *
+ * @return Returns the attributeCertificateValid.
+ */
+ public Date getAttributeCertificateValid()
+ {
+ if (attributeCertificateValid != null)
+ {
+ return new Date(attributeCertificateValid.getTime());
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets the holder.
+ *
+ * @return Returns the holder.
+ */
+ public AttributeCertificateHolder getHolder()
+ {
+ return holder;
+ }
+
+ /**
+ * Returns the issuer criterion.
+ *
+ * @return Returns the issuer.
+ */
+ public AttributeCertificateIssuer getIssuer()
+ {
+ return issuer;
+ }
+
+ /**
+ * Gets the serial number the attribute certificate must have.
+ *
+ * @return Returns the serialNumber.
+ */
+ public BigInteger getSerialNumber()
+ {
+ return serialNumber;
+ }
+
+ /**
+ * Gets the target names. The collection consists of GeneralName objects.
+ * <p>
+ * 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.
+ * <p>
+ * The returned collection is immutable.
+ *
+ * @return The collection of target groups.
+ */
+ public Collection getTargetGroups()
+ {
+ return targetGroups;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/selector/X509AttributeCertificateHolderSelectorBuilder.java b/pkix/src/main/java/org/spongycastle/cert/selector/X509AttributeCertificateHolderSelectorBuilder.java
new file mode 100644
index 00000000..35df571d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/selector/X509AttributeCertificateHolderSelectorBuilder.java
@@ -0,0 +1,194 @@
+package org.spongycastle.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.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.cert.AttributeCertificateHolder;
+import org.spongycastle.cert.AttributeCertificateIssuer;
+import org.spongycastle.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 <code>null</code> 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 <code>null</code>
+ * 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 <code>null</code> 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 <code>null</code>
+ * 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
+ * <code>null</code> 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 <code>X509AttributeCertificateHolder</code>
+ * must contain at least one of the specified target names.
+ * <p>
+ * 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 <code>null</code>)
+ */
+ public void addTargetName(GeneralName name)
+ {
+ targetNames.add(name);
+ }
+
+ /**
+ * Adds a collection with target names criteria. If <code>null</code> is
+ * given any will do.
+ * <p>
+ * 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.spongycastle.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 <code>X509AttributeCertificateHolder</code>
+ * must contain at least one of the specified target groups.
+ * <p>
+ * 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 <code>null</code>)
+ */
+ public void addTargetGroup(GeneralName group)
+ {
+ targetGroups.add(group);
+ }
+
+ /**
+ * Adds a collection with target groups criteria. If <code>null</code> is
+ * given any will do.
+ * <p>
+ * The collection consists of <code>GeneralName</code> objects or <code>byte[]</code representing DER
+ * encoded GeneralNames.
+ *
+ * @param names A collection of target groups.
+ * @throws java.io.IOException if a parsing error occurs.
+ * @see #addTargetGroup(org.spongycastle.asn1.x509.GeneralName)
+ */
+ public void setTargetGroups(Collection names) throws IOException
+ {
+ targetGroups = extractGeneralNames(names);
+ }
+
+ 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();)
+ {
+ temp.add(GeneralName.getInstance(it.next()));
+ }
+ return temp;
+ }
+
+ public X509AttributeCertificateHolderSelector build()
+ {
+ X509AttributeCertificateHolderSelector sel = new X509AttributeCertificateHolderSelector(
+ holder, issuer, serialNumber, attributeCertificateValid, attributeCert, Collections.unmodifiableCollection(new HashSet(targetNames)), Collections.unmodifiableCollection(new HashSet(targetGroups)));
+
+ return sel;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/selector/X509CertificateHolderSelector.java b/pkix/src/main/java/org/spongycastle/cert/selector/X509CertificateHolderSelector.java
new file mode 100644
index 00000000..8b6b88e3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/selector/X509CertificateHolderSelector.java
@@ -0,0 +1,152 @@
+package org.spongycastle.cert.selector;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.cms.IssuerAndSerialNumber;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java b/pkix/src/main/java/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java
new file mode 100644
index 00000000..551000b0
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java
@@ -0,0 +1,35 @@
+package org.spongycastle.cert.selector.jcajce;
+
+import java.io.IOException;
+import java.security.cert.X509CertSelector;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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());
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/java/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
new file mode 100644
index 00000000..6dbcef43
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
@@ -0,0 +1,57 @@
+package org.spongycastle.cert.selector.jcajce;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.X509CertSelector;
+
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java b/pkix/src/main/java/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java
new file mode 100644
index 00000000..fd73a9fa
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java
@@ -0,0 +1,72 @@
+package org.spongycastle.cert.selector.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.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;
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/AuthAttributesProvider.java b/pkix/src/main/java/org/spongycastle/cms/AuthAttributesProvider.java
new file mode 100644
index 00000000..d2f14c5b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/AuthAttributesProvider.java
@@ -0,0 +1,8 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.ASN1Set;
+
+interface AuthAttributesProvider
+{
+ ASN1Set getAuthAttributes();
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSAbsentContent.java b/pkix/src/main/java/org/spongycastle/cms/CMSAbsentContent.java
new file mode 100644
index 00000000..59409ea1
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSAbsentContent.java
@@ -0,0 +1,49 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSAlgorithm.java b/pkix/src/main/java/org/spongycastle/cms/CMSAlgorithm.java
new file mode 100644
index 00000000..aa04a47d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSAlgorithm.java
@@ -0,0 +1,51 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.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;
+
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSAttributeTableGenerationException.java b/pkix/src/main/java/org/spongycastle/cms/CMSAttributeTableGenerationException.java
new file mode 100644
index 00000000..e328f8e5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSAttributeTableGenerationException.java
@@ -0,0 +1,32 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSAttributeTableGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSAttributeTableGenerator.java
new file mode 100644
index 00000000..9c44be36
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSAttributeTableGenerator.java
@@ -0,0 +1,19 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.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;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSAuthEnvelopedData.java b/pkix/src/main/java/org/spongycastle/cms/CMSAuthEnvelopedData.java
new file mode 100644
index 00000000..df3ab5cf
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSAuthEnvelopedData.java
@@ -0,0 +1,78 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.cms.AuthEnvelopedData;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.EncryptedContentInfo;
+import org.spongycastle.asn1.cms.OriginatorInfo;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSAuthEnvelopedGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSAuthEnvelopedGenerator.java
new file mode 100644
index 00000000..f3a802cd
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSAuthEnvelopedGenerator.java
@@ -0,0 +1,13 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.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();
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedData.java b/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedData.java
new file mode 100644
index 00000000..898d5c0c
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedData.java
@@ -0,0 +1,260 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.AuthenticatedData;
+import org.spongycastle.asn1.cms.CMSAttributes;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.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.getAlgorithm().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 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedDataGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedDataGenerator.java
new file mode 100644
index 00000000..ca1f95a5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedDataGenerator.java
@@ -0,0 +1,181 @@
+package org.spongycastle.cms;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.BEROctetString;
+import org.spongycastle.asn1.BERSet;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.cms.AuthenticatedData;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.util.io.TeeOutputStream;
+
+/**
+ * General class for generating a CMS authenticated-data message.
+ *
+ * A simple example of usage.
+ *
+ * <pre>
+ * CMSAuthenticatedDataGenerator fact = new CMSAuthenticatedDataGenerator();
+ *
+ * adGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("SC"));
+ *
+ * CMSAuthenticatedData data = fact.generate(new CMSProcessableByteArray(data),
+ * new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build()));
+ * </pre>
+ */
+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;
+ }
+ });
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedDataParser.java b/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedDataParser.java
new file mode 100644
index 00000000..61a95e53
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedDataParser.java
@@ -0,0 +1,348 @@
+package org.spongycastle.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1OctetStringParser;
+import org.spongycastle.asn1.ASN1SequenceParser;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.ASN1SetParser;
+import org.spongycastle.asn1.BERTags;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.AuthenticatedDataParser;
+import org.spongycastle.asn1.cms.CMSAttributes;
+import org.spongycastle.asn1.cms.ContentInfoParser;
+import org.spongycastle.asn1.cms.OriginatorInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.util.Arrays;
+
+/**
+ * Parsing class for an CMS Authenticated Data object from an input stream.
+ * <p>
+ * 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.
+ * </p>
+ * <p>
+ * Example of use - assuming the first recipient matches the private key we have.
+ * <pre>
+ * 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("SC"));
+ *
+ * processDataStream(recData.getContentStream());
+ *
+ * if (!Arrays.equals(ad.getMac(), recipient.getMac())
+ * {
+ * System.err.println("Data corrupted!!!!");
+ * }
+ * }
+ * </pre>
+ * Note: this class does not introduce buffering - if you are processing large files you should create
+ * the parser with:
+ * <pre>
+ * CMSAuthenticatedDataParser ep = new CMSAuthenticatedDataParser(new BufferedInputStream(inputStream, bufSize));
+ * </pre>
+ * 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?
+ //ASN1Integer 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.getEncapsulatedContentInfo();
+ 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.getEncapsulatedContentInfo();
+ 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 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedDataStreamGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedDataStreamGenerator.java
new file mode 100644
index 00000000..14fbaa20
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedDataStreamGenerator.java
@@ -0,0 +1,310 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.BERSequenceGenerator;
+import org.spongycastle.asn1.BERSet;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.DERTaggedObject;
+import org.spongycastle.asn1.cms.AuthenticatedData;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.util.io.TeeOutputStream;
+
+/**
+ * General class for generating a CMS authenticated-data message stream.
+ * <p>
+ * A simple example of usage.
+ * <pre>
+ * CMSAuthenticatedDataStreamGenerator edGen = new CMSAuthenticatedDataStreamGenerator();
+ *
+ * edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(cert).setProvider("SC"));
+ *
+ * ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ *
+ * OutputStream out = edGen.open(
+ * bOut, new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider("SC").build());*
+ * out.write(data);
+ *
+ * out.close();
+ * </pre>
+ */
+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 ASN1Integer(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();
+ }
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedGenerator.java
new file mode 100644
index 00000000..718b09c0
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSAuthenticatedGenerator.java
@@ -0,0 +1,41 @@
+package org.spongycastle.cms;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.util.Arrays;
+
+public class CMSAuthenticatedGenerator
+ extends CMSEnvelopedGenerator
+{
+ protected CMSAttributeTableGenerator authGen;
+ protected CMSAttributeTableGenerator unauthGen;
+
+ /**
+ * base constructor
+ */
+ public CMSAuthenticatedGenerator()
+ {
+ }
+
+ 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, Arrays.clone(hash));
+ return param;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSCompressedData.java b/pkix/src/main/java/org/spongycastle/cms/CMSCompressedData.java
new file mode 100644
index 00000000..f6aa02d1
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSCompressedData.java
@@ -0,0 +1,107 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.cms.CompressedData;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.operator.InputExpander;
+import org.spongycastle.operator.InputExpanderProvider;
+
+/**
+ * containing class for an CMS Compressed Data object
+ * <pre>
+ * CMSCompressedData cd = new CMSCompressedData(inputStream);
+ *
+ * process(cd.getContent(new ZlibExpanderProvider()));
+ * </pre>
+ */
+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);
+ }
+ }
+
+ 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
+ */
+ public ContentInfo toASN1Structure()
+ {
+ return contentInfo;
+ }
+
+ /**
+ * return the ASN.1 encoded representation of this object.
+ */
+ public byte[] getEncoded()
+ throws IOException
+ {
+ return contentInfo.getEncoded();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSCompressedDataGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSCompressedDataGenerator.java
new file mode 100644
index 00000000..b26e84a3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSCompressedDataGenerator.java
@@ -0,0 +1,74 @@
+package org.spongycastle.cms;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.BEROctetString;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.CompressedData;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.OutputCompressor;
+
+/**
+ * General class for generating a compressed CMS message.
+ * <p>
+ * A simple example of usage.
+ * <p>
+ * <pre>
+ * CMSCompressedDataGenerator fact = new CMSCompressedDataGenerator();
+ *
+ * CMSCompressedData data = fact.generate(content, new ZlibCompressor());
+ * </pre>
+ */
+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
+ */
+ 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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSCompressedDataParser.java b/pkix/src/main/java/org/spongycastle/cms/CMSCompressedDataParser.java
new file mode 100644
index 00000000..bc853f2a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSCompressedDataParser.java
@@ -0,0 +1,72 @@
+package org.spongycastle.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1OctetStringParser;
+import org.spongycastle.asn1.ASN1SequenceParser;
+import org.spongycastle.asn1.BERTags;
+import org.spongycastle.asn1.cms.CompressedDataParser;
+import org.spongycastle.asn1.cms.ContentInfoParser;
+import org.spongycastle.operator.InputExpander;
+import org.spongycastle.operator.InputExpanderProvider;
+
+/**
+ * Class for reading a CMS Compressed Data stream.
+ * <pre>
+ * CMSCompressedDataParser cp = new CMSCompressedDataParser(inputStream);
+ *
+ * process(cp.getContent(new ZlibExpanderProvider()).getContentStream());
+ * </pre>
+ * Note: this class does not introduce buffering - if you are processing large files you should create
+ * the parser with:
+ * <pre>
+ * CMSCompressedDataParser ep = new CMSCompressedDataParser(new BufferedInputStream(inputStream, bufSize));
+ * </pre>
+ * 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);
+ }
+
+ /**
+ * 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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSCompressedDataStreamGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSCompressedDataStreamGenerator.java
new file mode 100644
index 00000000..47af9b4f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSCompressedDataStreamGenerator.java
@@ -0,0 +1,165 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.BERSequenceGenerator;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.operator.OutputCompressor;
+
+/**
+ * General class for generating a compressed CMS message stream.
+ * <p>
+ * A simple example of usage.
+ * </p>
+ * <pre>
+ * CMSCompressedDataStreamGenerator gen = new CMSCompressedDataStreamGenerator();
+ *
+ * OutputStream cOut = gen.open(outputStream, new ZlibCompressor());
+ *
+ * cOut.write(data);
+ *
+ * cOut.close();
+ * </pre>
+ */
+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;
+ }
+
+ /**
+ * Open a compressing output stream with the PKCS#7 content type OID of "data".
+ *
+ * @param out the stream to encode to.
+ * @param compressor the type of compressor to use.
+ * @return an output stream to write the data be compressed to.
+ * @throws IOException
+ */
+ public OutputStream open(
+ OutputStream out,
+ OutputCompressor compressor)
+ throws IOException
+ {
+ return open(CMSObjectIdentifiers.data, out, compressor);
+ }
+
+ /**
+ * Open a compressing output stream.
+ *
+ * @param contentOID the content type OID.
+ * @param out the stream to encode to.
+ * @param compressor the type of compressor to use.
+ * @return an output stream to write the data be compressed to.
+ * @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();
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSConfig.java b/pkix/src/main/java/org/spongycastle/cms/CMSConfig.java
new file mode 100644
index 00000000..d53a984f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSConfig.java
@@ -0,0 +1,34 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSContentInfoParser.java b/pkix/src/main/java/org/spongycastle/cms/CMSContentInfoParser.java
new file mode 100644
index 00000000..10ef9ffd
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSContentInfoParser.java
@@ -0,0 +1,45 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1SequenceParser;
+import org.spongycastle.asn1.ASN1StreamParser;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSDigestedData.java b/pkix/src/main/java/org/spongycastle/cms/CMSDigestedData.java
new file mode 100644
index 00000000..fb07fb53
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSDigestedData.java
@@ -0,0 +1,136 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.DigestedData;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.util.Arrays;
+
+/**
+ * containing class for an CMS Digested Data object
+ * <pre>
+ * CMSDigestedData cd = new CMSDigestedData(inputStream);
+ *
+ *
+ * process(cd.getContent());
+ * </pre>
+ */
+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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSEncryptedData.java b/pkix/src/main/java/org/spongycastle/cms/CMSEncryptedData.java
new file mode 100644
index 00000000..c833610a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSEncryptedData.java
@@ -0,0 +1,62 @@
+package org.spongycastle.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.EncryptedContentInfo;
+import org.spongycastle.asn1.cms.EncryptedData;
+import org.spongycastle.operator.InputDecryptor;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSEncryptedDataGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSEncryptedDataGenerator.java
new file mode 100644
index 00000000..b2a75087
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSEncryptedDataGenerator.java
@@ -0,0 +1,109 @@
+package org.spongycastle.cms;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.BEROctetString;
+import org.spongycastle.asn1.BERSet;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.EncryptedContentInfo;
+import org.spongycastle.asn1.cms.EncryptedData;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.OutputEncryptor;
+
+/**
+ * General class for generating a CMS enveloped-data message.
+ *
+ * A simple example of usage.
+ *
+ * <pre>
+ * CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes());
+ *
+ * CMSEncryptedDataGenerator edGen = new CMSEnvelopedDataGenerator();
+ *
+ * CMSEncryptedData ed = edGen.generate(
+ * msg,
+ * new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC)
+ * .setProvider("SC").build());
+ *
+ * </pre>
+ */
+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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSEncryptedGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSEncryptedGenerator.java
new file mode 100644
index 00000000..cce7a6d4
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSEncryptedGenerator.java
@@ -0,0 +1,21 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedData.java b/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedData.java
new file mode 100644
index 00000000..cc4cd30c
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedData.java
@@ -0,0 +1,206 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.EncryptedContentInfo;
+import org.spongycastle.asn1.cms.EnvelopedData;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * containing class for an CMS Enveloped Data object
+ * <p>
+ * Example of use - assuming the first recipient matches the private key we have.
+ * <pre>
+ * 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("SC"));
+ *
+ * processData(recData);
+ * }
+ * </pre>
+ */
+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
+ */
+ 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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedDataGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedDataGenerator.java
new file mode 100644
index 00000000..b23a8254
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedDataGenerator.java
@@ -0,0 +1,131 @@
+package org.spongycastle.cms;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.BEROctetString;
+import org.spongycastle.asn1.BERSet;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.EncryptedContentInfo;
+import org.spongycastle.asn1.cms.EnvelopedData;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OutputEncryptor;
+
+/**
+ * General class for generating a CMS enveloped-data message.
+ *
+ * A simple example of usage.
+ *
+ * <pre>
+ * CMSTypedData msg = new CMSProcessableByteArray("Hello World!".getBytes());
+ *
+ * CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
+ *
+ * edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("SC"));
+ *
+ * CMSEnvelopedData ed = edGen.generate(
+ * msg,
+ * new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC)
+ * .setProvider("SC").build());
+ *
+ * </pre>
+ */
+public class CMSEnvelopedDataGenerator
+ extends CMSEnvelopedGenerator
+{
+ /**
+ * base constructor
+ */
+ public CMSEnvelopedDataGenerator()
+ {
+ }
+
+ 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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedDataParser.java b/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedDataParser.java
new file mode 100644
index 00000000..ae821a6a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedDataParser.java
@@ -0,0 +1,208 @@
+package org.spongycastle.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1OctetStringParser;
+import org.spongycastle.asn1.ASN1SequenceParser;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.ASN1SetParser;
+import org.spongycastle.asn1.BERTags;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.EncryptedContentInfoParser;
+import org.spongycastle.asn1.cms.EnvelopedDataParser;
+import org.spongycastle.asn1.cms.OriginatorInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * Parsing class for an CMS Enveloped Data object from an input stream.
+ * <p>
+ * 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.
+ * </p>
+ * <p>
+ * Example of use - assuming the first recipient matches the private key we have.
+ * <pre>
+ * 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("SC"));
+ *
+ * processDataStream(recData.getContentStream());
+ * }
+ * </pre>
+ * Note: this class does not introduce buffering - if you are processing large files you should create
+ * the parser with:
+ * <pre>
+ * CMSEnvelopedDataParser ep = new CMSEnvelopedDataParser(new BufferedInputStream(inputStream, bufSize));
+ * </pre>
+ * 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?
+ //ASN1Integer 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedDataStreamGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedDataStreamGenerator.java
new file mode 100644
index 00000000..86f0a7c5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedDataStreamGenerator.java
@@ -0,0 +1,305 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.BERSequenceGenerator;
+import org.spongycastle.asn1.BERSet;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.DERTaggedObject;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.EnvelopedData;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OutputEncryptor;
+
+/**
+ * General class for generating a CMS enveloped-data message stream.
+ * <p>
+ * A simple example of usage.
+ * <pre>
+ * CMSEnvelopedDataStreamGenerator edGen = new CMSEnvelopedDataStreamGenerator();
+ *
+ * edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("SC"));
+ *
+ * ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ *
+ * OutputStream out = edGen.open(
+ * bOut, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC)
+ * .setProvider("SC").build());
+ * out.write(data);
+ *
+ * out.close();
+ * </pre>
+ */
+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 ASN1Integer getVersion()
+ {
+ if (originatorInfo != null || _unprotectedAttributes != null)
+ {
+ return new ASN1Integer(2);
+ }
+ else
+ {
+ return new ASN1Integer(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();
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedGenerator.java
new file mode 100644
index 00000000..c8702240
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedGenerator.java
@@ -0,0 +1,75 @@
+package org.spongycastle.cms;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.spongycastle.asn1.cms.OriginatorInfo;
+import org.spongycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.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;
+
+ protected OriginatorInfo originatorInfo;
+
+ /**
+ * base constructor
+ */
+ public CMSEnvelopedGenerator()
+ {
+ }
+
+ 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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedHelper.java b/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedHelper.java
new file mode 100644
index 00000000..e0a71f93
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSEnvelopedHelper.java
@@ -0,0 +1,203 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.cms.KEKRecipientInfo;
+import org.spongycastle.asn1.cms.KeyAgreeRecipientInfo;
+import org.spongycastle.asn1.cms.KeyTransRecipientInfo;
+import org.spongycastle.asn1.cms.PasswordRecipientInfo;
+import org.spongycastle.asn1.cms.RecipientInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.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();
+ }
+
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSException.java b/pkix/src/main/java/org/spongycastle/cms/CMSException.java
new file mode 100644
index 00000000..dd840120
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSException.java
@@ -0,0 +1,32 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSProcessable.java b/pkix/src/main/java/org/spongycastle/cms/CMSProcessable.java
new file mode 100644
index 00000000..ed27eb15
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSProcessable.java
@@ -0,0 +1,21 @@
+package org.spongycastle.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.
+ * <p>
+ * Note: this routine may be called multiple times.
+ */
+ public void write(OutputStream out)
+ throws IOException, CMSException;
+
+ public Object getContent();
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSProcessableByteArray.java b/pkix/src/main/java/org/spongycastle/cms/CMSProcessableByteArray.java
new file mode 100644
index 00000000..2732a26e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSProcessableByteArray.java
@@ -0,0 +1,55 @@
+package org.spongycastle.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSProcessableFile.java b/pkix/src/main/java/org/spongycastle/cms/CMSProcessableFile.java
new file mode 100644
index 00000000..6415dd5d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSProcessableFile.java
@@ -0,0 +1,80 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSProcessableInputStream.java b/pkix/src/main/java/org/spongycastle/cms/CMSProcessableInputStream.java
new file mode 100644
index 00000000..fc644c95
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSProcessableInputStream.java
@@ -0,0 +1,50 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSReadable.java b/pkix/src/main/java/org/spongycastle/cms/CMSReadable.java
new file mode 100644
index 00000000..ecf79a43
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSReadable.java
@@ -0,0 +1,10 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+interface CMSReadable
+{
+ public InputStream getInputStream()
+ throws IOException, CMSException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSRuntimeException.java b/pkix/src/main/java/org/spongycastle/cms/CMSRuntimeException.java
new file mode 100644
index 00000000..29805bb2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSRuntimeException.java
@@ -0,0 +1,32 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSSecureReadable.java b/pkix/src/main/java/org/spongycastle/cms/CMSSecureReadable.java
new file mode 100644
index 00000000..b16aef11
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSSecureReadable.java
@@ -0,0 +1,10 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+interface CMSSecureReadable
+{
+ InputStream getInputStream()
+ throws IOException, CMSException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSSignatureAlgorithmNameGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSSignatureAlgorithmNameGenerator.java
new file mode 100644
index 00000000..8941a90b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSSignatureAlgorithmNameGenerator.java
@@ -0,0 +1,15 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.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);
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java b/pkix/src/main/java/org/spongycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java
new file mode 100644
index 00000000..886b4101
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java
@@ -0,0 +1,17 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.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);
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSSignedData.java b/pkix/src/main/java/org/spongycastle/cms/CMSSignedData.java
new file mode 100644
index 00000000..f8127d6d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSSignedData.java
@@ -0,0 +1,543 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.BERSequence;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.SignedData;
+import org.spongycastle.asn1.cms.SignerInfo;
+import org.spongycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.SignatureAlgorithmIdentifierFinder;
+import org.spongycastle.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...
+ *
+ * <pre>
+ * 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("SC").build(cert)))
+ * {
+ * verified++;
+ * }
+ * }
+ * </pre>
+ */
+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 revocations the new CRLs to be used - a collection of X509CRLHolder objects, OtherRevocationInfoFormat, or both.
+ * @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 revocations)
+ throws CMSException
+ {
+ //
+ // copy
+ //
+ CMSSignedData cms = new CMSSignedData(signedData);
+
+ //
+ // replace the certs and revocations 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 (revocations != null)
+ {
+ ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(revocations));
+
+ 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSSignedDataGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSSignedDataGenerator.java
new file mode 100644
index 00000000..70dce12a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSSignedDataGenerator.java
@@ -0,0 +1,232 @@
+package org.spongycastle.cms;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.BEROctetString;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.SignedData;
+import org.spongycastle.asn1.cms.SignerInfo;
+
+/**
+ * general class for generating a pkcs7-signature message.
+ * <p>
+ * A simple example of usage, generating a detached signature.
+ *
+ * <pre>
+ * 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("SC").build(signKP.getPrivate());
+ *
+ * gen.addSignerInfoGenerator(
+ * new JcaSignerInfoGeneratorBuilder(
+ * new JcaDigestCalculatorProviderBuilder().setProvider("SC").build())
+ * .build(sha1Signer, signCert));
+ *
+ * gen.addCertificates(certs);
+ *
+ * CMSSignedData sigData = gen.generate(msg, false);
+ * </pre>
+ */
+public class CMSSignedDataGenerator
+ extends CMSSignedGenerator
+{
+ private List signerInfs = new ArrayList();
+
+ /**
+ * base constructor
+ */
+ public CMSSignedDataGenerator()
+ {
+ }
+
+ /**
+ * Generate a CMS Signed Data object carrying a detached CMS signature.
+ *
+ * @param content the content to be signed.
+ */
+ public CMSSignedData generate(
+ CMSTypedData content)
+ throws CMSException
+ {
+ return generate(content, false);
+ }
+
+ /**
+ * Generate a CMS Signed Data object which can be carrying a detached CMS signature, or have encapsulated data, depending on the value
+ * of the encapsulated parameter.
+ *
+ * @param content the content to be signed.
+ * @param encapsulate true if the content should be encapsulated in the signature, false otherwise.
+ */
+ 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.getContent() != 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();
+ }
+}
+
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSSignedDataParser.java b/pkix/src/main/java/org/spongycastle/cms/CMSSignedDataParser.java
new file mode 100644
index 00000000..89edf873
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSSignedDataParser.java
@@ -0,0 +1,624 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Generator;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetStringParser;
+import org.spongycastle.asn1.ASN1SequenceParser;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.ASN1SetParser;
+import org.spongycastle.asn1.ASN1StreamParser;
+import org.spongycastle.asn1.BERSequenceGenerator;
+import org.spongycastle.asn1.BERSetParser;
+import org.spongycastle.asn1.BERTaggedObject;
+import org.spongycastle.asn1.BERTags;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.DERTaggedObject;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfoParser;
+import org.spongycastle.asn1.cms.SignedDataParser;
+import org.spongycastle.asn1.cms.SignerInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.util.Store;
+import org.spongycastle.util.io.Streams;
+
+/**
+ * Parsing class for an CMS Signed Data object from an input stream.
+ * <p>
+ * 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.
+ * </p>
+ * <p>
+ * A simple example of usage for an encapsulated signature.
+ * </p>
+ * <p>
+ * 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.
+ * </p>
+ * <pre>
+ * CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider("SC").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("SC").build(cert)));
+ * }
+ * </pre>
+ * Note also: this class does not introduce buffering - if you are processing large files you should create
+ * the parser with:
+ * <pre>
+ * CMSSignedDataParser ep = new CMSSignedDataParser(new BufferedInputStream(encapSigData, bufSize));
+ * </pre>
+ * 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 ASN1Set _certSet, _crlSet;
+ private boolean _isCertCrlParsed;
+
+ 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));
+ }
+
+ /**
+ * 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);
+ }
+ }
+
+ /**
+ * 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.
+ * <p>
+ * The output stream is returned unclosed.
+ * </p>
+ * @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.
+ * <p>
+ * The output stream is returned unclosed.
+ * </p>
+ * @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());
+// }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSSignedDataStreamGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSSignedDataStreamGenerator.java
new file mode 100644
index 00000000..15a94bf5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSSignedDataStreamGenerator.java
@@ -0,0 +1,486 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.BERSequenceGenerator;
+import org.spongycastle.asn1.BERTaggedObject;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.SignerInfo;
+
+/**
+ * General class for generating a pkcs7-signature message stream.
+ * <p>
+ * A simple example of usage.
+ * </p>
+ * <pre>
+ * X509Certificate signCert = ...
+ * certList.add(signCert);
+ *
+ * Store certs = new JcaCertStore(certList);
+ * ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("SC").build(signKP.getPrivate());
+ *
+ * CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
+ *
+ * gen.addSignerInfoGenerator(
+ * new JcaSignerInfoGeneratorBuilder(
+ * new JcaDigestCalculatorProviderBuilder().setProvider("SC").build())
+ * .build(sha1Signer, signCert));
+ *
+ * gen.addCertificates(certs);
+ *
+ * OutputStream sigOut = gen.open(bOut);
+ *
+ * sigOut.write("Hello World!".getBytes());
+ *
+ * sigOut.close();
+ * </pre>
+ */
+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);
+ }
+
+ // 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() == 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();
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSSignedGenerator.java b/pkix/src/main/java/org/spongycastle/cms/CMSSignedGenerator.java
new file mode 100644
index 00000000..b2747d9f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSSignedGenerator.java
@@ -0,0 +1,239 @@
+package org.spongycastle.cms;
+
+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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERTaggedObject;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.OtherRevocationInfoFormat;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.cert.X509AttributeCertificateHolder;
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.Store;
+
+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();
+
+ /**
+ * base constructor
+ */
+ protected CMSSignedGenerator()
+ {
+ }
+
+ 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;
+ }
+
+ /**
+ * 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 pre-calculated 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());
+ }
+ }
+
+ /**
+ * Add a generator for a particular signer to this CMS SignedData generator.
+ *
+ * @param infoGen the generator representing the particular signer.
+ */
+ 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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSSignedHelper.java b/pkix/src/main/java/org/spongycastle/cms/CMSSignedHelper.java
new file mode 100644
index 00000000..1f4187bc
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSSignedHelper.java
@@ -0,0 +1,253 @@
+package org.spongycastle.cms;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.cms.OtherRevocationInfoFormat;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.eac.EACObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.AttributeCertificate;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.CertificateList;
+import org.spongycastle.asn1.x509.X509ObjectIdentifiers;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.cert.X509AttributeCertificateHolder;
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.util.CollectionStore;
+import org.spongycastle.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 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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSSignerDigestMismatchException.java b/pkix/src/main/java/org/spongycastle/cms/CMSSignerDigestMismatchException.java
new file mode 100644
index 00000000..c2bf8a26
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSSignerDigestMismatchException.java
@@ -0,0 +1,11 @@
+package org.spongycastle.cms;
+
+public class CMSSignerDigestMismatchException
+ extends CMSException
+{
+ public CMSSignerDigestMismatchException(
+ String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSStreamException.java b/pkix/src/main/java/org/spongycastle/cms/CMSStreamException.java
new file mode 100644
index 00000000..65550353
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSStreamException.java
@@ -0,0 +1,26 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSTypedData.java b/pkix/src/main/java/org/spongycastle/cms/CMSTypedData.java
new file mode 100644
index 00000000..eb044d95
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSTypedData.java
@@ -0,0 +1,9 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+
+public interface CMSTypedData
+ extends CMSProcessable
+{
+ ASN1ObjectIdentifier getContentType();
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSTypedStream.java b/pkix/src/main/java/org/spongycastle/cms/CMSTypedStream.java
new file mode 100644
index 00000000..74984427
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSTypedStream.java
@@ -0,0 +1,86 @@
+package org.spongycastle.cms;
+
+import java.io.BufferedInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.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;
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSUtils.java b/pkix/src/main/java/org/spongycastle/cms/CMSUtils.java
new file mode 100644
index 00000000..eaaadf86
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSUtils.java
@@ -0,0 +1,335 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.ASN1TaggedObject;
+import org.spongycastle.asn1.BEROctetStringGenerator;
+import org.spongycastle.asn1.BERSet;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.DERTaggedObject;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.OtherRevocationInfoFormat;
+import org.spongycastle.asn1.ocsp.OCSPResponse;
+import org.spongycastle.asn1.ocsp.OCSPResponseStatus;
+import org.spongycastle.cert.X509AttributeCertificateHolder;
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.util.Store;
+import org.spongycastle.util.Strings;
+import org.spongycastle.util.io.Streams;
+import org.spongycastle.util.io.TeeInputStream;
+import org.spongycastle.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 crls = new ArrayList();
+
+ try
+ {
+ for (Iterator it = crlStore.getMatches(null).iterator(); it.hasNext();)
+ {
+ Object rev = it.next();
+
+ if (rev instanceof X509CRLHolder)
+ {
+ X509CRLHolder c = (X509CRLHolder)rev;
+
+ crls.add(c.toASN1Structure());
+ }
+ else if (rev instanceof OtherRevocationInfoFormat)
+ {
+ OtherRevocationInfoFormat infoFormat = OtherRevocationInfoFormat.getInstance(rev);
+
+ validateInfoFormat(infoFormat);
+
+ crls.add(new DERTaggedObject(false, 1, infoFormat));
+ }
+ else if (rev instanceof ASN1TaggedObject)
+ {
+ crls.add(rev);
+ }
+ }
+
+ return crls;
+ }
+ catch (ClassCastException e)
+ {
+ throw new CMSException("error processing certs", e);
+ }
+ }
+
+ private static void validateInfoFormat(OtherRevocationInfoFormat infoFormat)
+ {
+ if (CMSObjectIdentifiers.id_ri_ocsp_response.equals(infoFormat.getInfoFormat()))
+ {
+ OCSPResponse resp = OCSPResponse.getInstance(infoFormat.getInfo());
+
+ if (resp.getResponseStatus().getValue().intValue() != OCSPResponseStatus.SUCCESSFUL)
+ {
+ throw new IllegalArgumentException("cannot add unsuccessful OCSP response to CMS SignedData");
+ }
+ }
+ }
+
+ 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();
+ OtherRevocationInfoFormat infoFormat = new OtherRevocationInfoFormat(otherRevocationInfoFormat, info);
+
+ validateInfoFormat(infoFormat);
+
+ others.add(new DERTaggedObject(false, 1, infoFormat));
+ }
+
+ 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);
+ }
+ }
+
+ static byte[] getPasswordBytes(int scheme, char[] password)
+ {
+ if (scheme == PasswordRecipient.PKCS5_SCHEME2)
+ {
+ return PKCS5PasswordToBytes(password);
+ }
+
+ return PKCS5PasswordToUTF8Bytes(password);
+ }
+
+ /**
+ * 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.
+ */
+ private 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.
+ */
+ private static byte[] PKCS5PasswordToUTF8Bytes(
+ char[] password)
+ {
+ if (password != null)
+ {
+ return Strings.toUTF8ByteArray(password);
+ }
+ else
+ {
+ return new byte[0];
+ }
+ }
+
+ 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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/CMSVerifierCertificateNotValidException.java b/pkix/src/main/java/org/spongycastle/cms/CMSVerifierCertificateNotValidException.java
new file mode 100644
index 00000000..bdcf131b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/CMSVerifierCertificateNotValidException.java
@@ -0,0 +1,11 @@
+package org.spongycastle.cms;
+
+public class CMSVerifierCertificateNotValidException
+ extends CMSException
+{
+ public CMSVerifierCertificateNotValidException(
+ String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java b/pkix/src/main/java/org/spongycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java
new file mode 100644
index 00000000..ab3628d5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java
@@ -0,0 +1,99 @@
+package org.spongycastle.cms;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.cms.Attribute;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.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 = new Hashtable();
+
+ for (Enumeration en = table.keys(); en.hasMoreElements();)
+ {
+ Object key = en.nextElement();
+
+ std.put(key, table.get(key));
+ }
+
+ 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));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java b/pkix/src/main/java/org/spongycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
new file mode 100644
index 00000000..1975968b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
@@ -0,0 +1,161 @@
+package org.spongycastle.cms;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.bsi.BSIObjectIdentifiers;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.eac.EACObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.X509ObjectIdentifiers;
+import org.spongycastle.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");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512", "PLAIN-ECDSA");
+ addEntries(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160", "PLAIN-ECDSA");
+
+ 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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java b/pkix/src/main/java/org/spongycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
new file mode 100644
index 00000000..4608bb10
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
@@ -0,0 +1,46 @@
+package org.spongycastle.cms;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/DefaultSignedAttributeTableGenerator.java b/pkix/src/main/java/org/spongycastle/cms/DefaultSignedAttributeTableGenerator.java
new file mode 100644
index 00000000..ba570c28
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/DefaultSignedAttributeTableGenerator.java
@@ -0,0 +1,121 @@
+package org.spongycastle.cms;
+
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.cms.Attribute;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSAttributes;
+import org.spongycastle.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 = copyHashTable(table);
+
+ 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));
+ }
+
+ private static Hashtable copyHashTable(Hashtable paramsMap)
+ {
+ Hashtable newTable = new Hashtable();
+
+ Enumeration keys = paramsMap.keys();
+ while (keys.hasMoreElements())
+ {
+ Object key = keys.nextElement();
+ newTable.put(key, paramsMap.get(key));
+ }
+
+ return newTable;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/KEKRecipient.java b/pkix/src/main/java/org/spongycastle/cms/KEKRecipient.java
new file mode 100644
index 00000000..3b14a89d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/KEKRecipient.java
@@ -0,0 +1,10 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface KEKRecipient
+ extends Recipient
+{
+ RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentKey)
+ throws CMSException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/KEKRecipientId.java b/pkix/src/main/java/org/spongycastle/cms/KEKRecipientId.java
new file mode 100644
index 00000000..2025c7c1
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/KEKRecipientId.java
@@ -0,0 +1,63 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/KEKRecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/KEKRecipientInfoGenerator.java
new file mode 100644
index 00000000..480fb5fe
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/KEKRecipientInfoGenerator.java
@@ -0,0 +1,39 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.cms.KEKIdentifier;
+import org.spongycastle.asn1.cms.KEKRecipientInfo;
+import org.spongycastle.asn1.cms.RecipientInfo;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OperatorException;
+import org.spongycastle.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);
+ }
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/KEKRecipientInformation.java b/pkix/src/main/java/org/spongycastle/cms/KEKRecipientInformation.java
new file mode 100644
index 00000000..3388d6fa
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/KEKRecipientInformation.java
@@ -0,0 +1,38 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.cms.KEKIdentifier;
+import org.spongycastle.asn1.cms.KEKRecipientInfo;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipient.java b/pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipient.java
new file mode 100644
index 00000000..ab3a7451
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipient.java
@@ -0,0 +1,14 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+
+public interface KeyAgreeRecipient
+ extends Recipient
+{
+ RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier contentEncryptionAlgorithm, SubjectPublicKeyInfo senderPublicKey, ASN1OctetString userKeyingMaterial, byte[] encryptedContentKey)
+ throws CMSException;
+
+ AlgorithmIdentifier getPrivateKeyAlgorithmIdentifier();
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipientId.java b/pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipientId.java
new file mode 100644
index 00000000..c5f2aa14
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipientId.java
@@ -0,0 +1,89 @@
+package org.spongycastle.cms;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipientInfoGenerator.java
new file mode 100644
index 00000000..b80ec375
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipientInfoGenerator.java
@@ -0,0 +1,80 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.cms.KeyAgreeRecipientInfo;
+import org.spongycastle.asn1.cms.OriginatorIdentifierOrKey;
+import org.spongycastle.asn1.cms.OriginatorPublicKey;
+import org.spongycastle.asn1.cms.RecipientInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.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;
+
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipientInformation.java b/pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipientInformation.java
new file mode 100644
index 00000000..c00dcdf3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/KeyAgreeRecipientInformation.java
@@ -0,0 +1,131 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.cms.IssuerAndSerialNumber;
+import org.spongycastle.asn1.cms.KeyAgreeRecipientIdentifier;
+import org.spongycastle.asn1.cms.KeyAgreeRecipientInfo;
+import org.spongycastle.asn1.cms.OriginatorIdentifierOrKey;
+import org.spongycastle.asn1.cms.OriginatorPublicKey;
+import org.spongycastle.asn1.cms.RecipientEncryptedKey;
+import org.spongycastle.asn1.cms.RecipientKeyIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/KeyTransRecipient.java b/pkix/src/main/java/org/spongycastle/cms/KeyTransRecipient.java
new file mode 100644
index 00000000..04201d0d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/KeyTransRecipient.java
@@ -0,0 +1,10 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface KeyTransRecipient
+ extends Recipient
+{
+ RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncAlg, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] encryptedContentKey)
+ throws CMSException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/KeyTransRecipientId.java b/pkix/src/main/java/org/spongycastle/cms/KeyTransRecipientId.java
new file mode 100644
index 00000000..b76e19f4
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/KeyTransRecipientId.java
@@ -0,0 +1,102 @@
+package org.spongycastle.cms;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/KeyTransRecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/KeyTransRecipientInfoGenerator.java
new file mode 100644
index 00000000..c78a4ff8
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/KeyTransRecipientInfoGenerator.java
@@ -0,0 +1,58 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.cms.IssuerAndSerialNumber;
+import org.spongycastle.asn1.cms.KeyTransRecipientInfo;
+import org.spongycastle.asn1.cms.RecipientIdentifier;
+import org.spongycastle.asn1.cms.RecipientInfo;
+import org.spongycastle.operator.AsymmetricKeyWrapper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.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)));
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/KeyTransRecipientInformation.java b/pkix/src/main/java/org/spongycastle/cms/KeyTransRecipientInformation.java
new file mode 100644
index 00000000..f671b8cd
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/KeyTransRecipientInformation.java
@@ -0,0 +1,50 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.cms.IssuerAndSerialNumber;
+import org.spongycastle.asn1.cms.KeyTransRecipientInfo;
+import org.spongycastle.asn1.cms.RecipientIdentifier;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/NullOutputStream.java b/pkix/src/main/java/org/spongycastle/cms/NullOutputStream.java
new file mode 100644
index 00000000..c5ccd4ec
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/NullOutputStream.java
@@ -0,0 +1,28 @@
+/**
+ *
+ */
+package org.spongycastle.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
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/OriginatorId.java b/pkix/src/main/java/org/spongycastle/cms/OriginatorId.java
new file mode 100644
index 00000000..eee06cea
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/OriginatorId.java
@@ -0,0 +1,118 @@
+package org.spongycastle.cms;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/OriginatorInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/OriginatorInfoGenerator.java
new file mode 100644
index 00000000..fd70ab52
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/OriginatorInfoGenerator.java
@@ -0,0 +1,54 @@
+package org.spongycastle.cms;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.spongycastle.asn1.cms.OriginatorInfo;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.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));
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/OriginatorInformation.java b/pkix/src/main/java/org/spongycastle/cms/OriginatorInformation.java
new file mode 100644
index 00000000..4db9a10a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/OriginatorInformation.java
@@ -0,0 +1,95 @@
+package org.spongycastle.cms;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.cms.OriginatorInfo;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.CertificateList;
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.util.CollectionStore;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/PasswordRecipient.java b/pkix/src/main/java/org/spongycastle/cms/PasswordRecipient.java
new file mode 100644
index 00000000..616f25ca
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/PasswordRecipient.java
@@ -0,0 +1,20 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface PasswordRecipient
+ extends Recipient
+{
+ public static final int PKCS5_SCHEME2 = 0;
+ public static final int PKCS5_SCHEME2_UTF8 = 1;
+
+ byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
+ throws CMSException;
+
+ RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] derivedKey, byte[] encryptedEncryptedContentKey)
+ throws CMSException;
+
+ int getPasswordConversionScheme();
+
+ char[] getPassword();
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/PasswordRecipientId.java b/pkix/src/main/java/org/spongycastle/cms/PasswordRecipientId.java
new file mode 100644
index 00000000..d3efe2f5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/PasswordRecipientId.java
@@ -0,0 +1,44 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/PasswordRecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/PasswordRecipientInfoGenerator.java
new file mode 100644
index 00000000..33c34b7a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/PasswordRecipientInfoGenerator.java
@@ -0,0 +1,122 @@
+package org.spongycastle.cms;
+
+import java.security.SecureRandom;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.cms.PasswordRecipientInfo;
+import org.spongycastle.asn1.cms.RecipientInfo;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.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));
+ }
+
+ byte[] encodedPassword = CMSUtils.getPasswordBytes(schemeID, password);
+
+ byte[] derivedKey = calculateDerivedKey(encodedPassword, keyDerivationAlgorithm, keySize);
+
+ 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[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
+ throws CMSException;
+
+ protected abstract byte[] generateEncryptedBytes(AlgorithmIdentifier algorithm, byte[] derivedKey, GenericKey contentEncryptionKey)
+ throws CMSException;
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/PasswordRecipientInformation.java b/pkix/src/main/java/org/spongycastle/cms/PasswordRecipientInformation.java
new file mode 100644
index 00000000..2c9efbac
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/PasswordRecipientInformation.java
@@ -0,0 +1,116 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.cms.PasswordRecipientInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.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 = CMSUtils.getPasswordBytes(pbeRecipient.getPasswordConversionScheme(), pbeRecipient.getPassword());
+
+ int keySize = ((Integer)KEYSIZES.get(kekAlgParams.getAlgorithm())).intValue();
+
+ byte[] derivedKey = pbeRecipient.calculateDerivedKey(passwordBytes, this.getKeyDerivationAlgorithm(), keySize);
+
+ return pbeRecipient.getRecipientOperator(kekAlgParams, messageAlgorithm, derivedKey, info.getEncryptedKey().getOctets());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/Recipient.java b/pkix/src/main/java/org/spongycastle/cms/Recipient.java
new file mode 100644
index 00000000..17a3e4f8
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/Recipient.java
@@ -0,0 +1,5 @@
+package org.spongycastle.cms;
+
+public interface Recipient
+{
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/RecipientId.java b/pkix/src/main/java/org/spongycastle/cms/RecipientId.java
new file mode 100644
index 00000000..78a4bc22
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/RecipientId.java
@@ -0,0 +1,31 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.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();
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/RecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/RecipientInfoGenerator.java
new file mode 100644
index 00000000..f61b3d97
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/RecipientInfoGenerator.java
@@ -0,0 +1,10 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.cms.RecipientInfo;
+import org.spongycastle.operator.GenericKey;
+
+public interface RecipientInfoGenerator
+{
+ RecipientInfo generate(GenericKey contentEncryptionKey)
+ throws CMSException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/RecipientInformation.java b/pkix/src/main/java/org/spongycastle/cms/RecipientInformation.java
new file mode 100644
index 00000000..c083baa9
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/RecipientInformation.java
@@ -0,0 +1,181 @@
+package org.spongycastle.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.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.getAlgorithm().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)
+ {
+ 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);
+ }
+ }
+
+ /**
+ * 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;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/RecipientInformationStore.java b/pkix/src/main/java/org/spongycastle/cms/RecipientInformationStore.java
new file mode 100644
index 00000000..f995874c
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/RecipientInformationStore.java
@@ -0,0 +1,115 @@
+package org.spongycastle.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.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/RecipientOperator.java b/pkix/src/main/java/org/spongycastle/cms/RecipientOperator.java
new file mode 100644
index 00000000..c254dbf3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/RecipientOperator.java
@@ -0,0 +1,48 @@
+package org.spongycastle.cms;
+
+import java.io.InputStream;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.InputDecryptor;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/SignerId.java b/pkix/src/main/java/org/spongycastle/cms/SignerId.java
new file mode 100644
index 00000000..a7434f8a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/SignerId.java
@@ -0,0 +1,104 @@
+package org.spongycastle.cms;
+
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cert.selector.X509CertificateHolderSelector;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/SignerInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/SignerInfoGenerator.java
new file mode 100644
index 00000000..6e5a8088
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/SignerInfoGenerator.java
@@ -0,0 +1,291 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.SignerIdentifier;
+import org.spongycastle.asn1.cms.SignerInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.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 int getGeneratedVersion()
+ {
+ return 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, 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(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, 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/SignerInfoGeneratorBuilder.java b/pkix/src/main/java/org/spongycastle/cms/SignerInfoGeneratorBuilder.java
new file mode 100644
index 00000000..a33005e0
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/SignerInfoGeneratorBuilder.java
@@ -0,0 +1,139 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.cms.IssuerAndSerialNumber;
+import org.spongycastle.asn1.cms.SignerIdentifier;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/SignerInformation.java b/pkix/src/main/java/org/spongycastle/cms/SignerInformation.java
new file mode 100644
index 00000000..353f27e6
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/SignerInformation.java
@@ -0,0 +1,680 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.cms.Attribute;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSAttributes;
+import org.spongycastle.asn1.cms.IssuerAndSerialNumber;
+import org.spongycastle.asn1.cms.SignerIdentifier;
+import org.spongycastle.asn1.cms.SignerInfo;
+import org.spongycastle.asn1.cms.Time;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.DigestInfo;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.RawContentVerifier;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.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 Arrays.clone(resultDigest);
+ }
+
+ /**
+ * 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 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());
+ 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 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.spongycastle.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.spongycastle.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 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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/SignerInformationStore.java b/pkix/src/main/java/org/spongycastle/cms/SignerInformationStore.java
new file mode 100644
index 00000000..df3bb968
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/SignerInformationStore.java
@@ -0,0 +1,109 @@
+package org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/SignerInformationVerifier.java b/pkix/src/main/java/org/spongycastle/cms/SignerInformationVerifier.java
new file mode 100644
index 00000000..ea9de675
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/SignerInformationVerifier.java
@@ -0,0 +1,50 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/SignerInformationVerifierProvider.java b/pkix/src/main/java/org/spongycastle/cms/SignerInformationVerifierProvider.java
new file mode 100644
index 00000000..d6e7d6e5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/SignerInformationVerifierProvider.java
@@ -0,0 +1,16 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.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;
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/SimpleAttributeTableGenerator.java b/pkix/src/main/java/org/spongycastle/cms/SimpleAttributeTableGenerator.java
new file mode 100644
index 00000000..25c55b78
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/SimpleAttributeTableGenerator.java
@@ -0,0 +1,25 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/BcCMSContentEncryptorBuilder.java b/pkix/src/main/java/org/spongycastle/cms/bc/BcCMSContentEncryptorBuilder.java
new file mode 100644
index 00000000..22f79fb7
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/BcCMSContentEncryptorBuilder.java
@@ -0,0 +1,124 @@
+package org.spongycastle.cms.bc;
+
+import java.io.OutputStream;
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.crypto.BufferedBlockCipher;
+import org.spongycastle.crypto.CipherKeyGenerator;
+import org.spongycastle.crypto.StreamCipher;
+import org.spongycastle.crypto.io.CipherOutputStream;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.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());
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/BcKEKEnvelopedRecipient.java b/pkix/src/main/java/org/spongycastle/cms/bc/BcKEKEnvelopedRecipient.java
new file mode 100644
index 00000000..afde8a02
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/BcKEKEnvelopedRecipient.java
@@ -0,0 +1,49 @@
+package org.spongycastle.cms.bc;
+
+import java.io.InputStream;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.RecipientOperator;
+import org.spongycastle.crypto.BufferedBlockCipher;
+import org.spongycastle.crypto.StreamCipher;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.operator.InputDecryptor;
+import org.spongycastle.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.spongycastle.crypto.io.CipherInputStream(dataOut, (BufferedBlockCipher)dataCipher);
+ }
+ else
+ {
+ return new org.spongycastle.crypto.io.CipherInputStream(dataOut, (StreamCipher)dataCipher);
+ }
+ }
+ });
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/BcKEKRecipient.java b/pkix/src/main/java/org/spongycastle/cms/bc/BcKEKRecipient.java
new file mode 100644
index 00000000..066deaa6
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/BcKEKRecipient.java
@@ -0,0 +1,33 @@
+package org.spongycastle.cms.bc;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.KEKRecipient;
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.operator.OperatorException;
+import org.spongycastle.operator.SymmetricKeyUnwrapper;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/BcKEKRecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/bc/BcKEKRecipientInfoGenerator.java
new file mode 100644
index 00000000..2a2ad9e7
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/BcKEKRecipientInfoGenerator.java
@@ -0,0 +1,19 @@
+package org.spongycastle.cms.bc;
+
+import org.spongycastle.asn1.cms.KEKIdentifier;
+import org.spongycastle.cms.KEKRecipientInfoGenerator;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/BcKeyTransRecipient.java b/pkix/src/main/java/org/spongycastle/cms/bc/BcKeyTransRecipient.java
new file mode 100644
index 00000000..ab50269d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/BcKeyTransRecipient.java
@@ -0,0 +1,36 @@
+package org.spongycastle.cms.bc;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.KeyTransRecipient;
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.operator.AsymmetricKeyUnwrapper;
+import org.spongycastle.operator.OperatorException;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/BcKeyTransRecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/bc/BcKeyTransRecipientInfoGenerator.java
new file mode 100644
index 00000000..c987d5a2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/BcKeyTransRecipientInfoGenerator.java
@@ -0,0 +1,20 @@
+package org.spongycastle.cms.bc;
+
+import org.spongycastle.asn1.cms.IssuerAndSerialNumber;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cms.KeyTransRecipientInfoGenerator;
+import org.spongycastle.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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/BcPasswordEnvelopedRecipient.java b/pkix/src/main/java/org/spongycastle/cms/bc/BcPasswordEnvelopedRecipient.java
new file mode 100644
index 00000000..0b9a529f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/BcPasswordEnvelopedRecipient.java
@@ -0,0 +1,49 @@
+package org.spongycastle.cms.bc;
+
+import java.io.InputStream;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.RecipientOperator;
+import org.spongycastle.crypto.BufferedBlockCipher;
+import org.spongycastle.crypto.StreamCipher;
+import org.spongycastle.crypto.io.CipherInputStream;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.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);
+ }
+ }
+ });
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/BcPasswordRecipient.java b/pkix/src/main/java/org/spongycastle/cms/bc/BcPasswordRecipient.java
new file mode 100644
index 00000000..679f4144
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/BcPasswordRecipient.java
@@ -0,0 +1,75 @@
+package org.spongycastle.cms.bc;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.PasswordRecipient;
+import org.spongycastle.crypto.InvalidCipherTextException;
+import org.spongycastle.crypto.Wrapper;
+import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.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 byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
+ throws CMSException
+ {
+ PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters());
+
+ PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
+
+ gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue());
+
+ return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey();
+ }
+
+ public int getPasswordConversionScheme()
+ {
+ return schemeID;
+ }
+
+ public char[] getPassword()
+ {
+ return password;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/BcPasswordRecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/bc/BcPasswordRecipientInfoGenerator.java
new file mode 100644
index 00000000..4ea5cdfd
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/BcPasswordRecipientInfoGenerator.java
@@ -0,0 +1,45 @@
+package org.spongycastle.cms.bc;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.PasswordRecipientInfoGenerator;
+import org.spongycastle.crypto.Wrapper;
+import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.crypto.params.ParametersWithIV;
+import org.spongycastle.operator.GenericKey;
+
+public class BcPasswordRecipientInfoGenerator
+ extends PasswordRecipientInfoGenerator
+{
+ public BcPasswordRecipientInfoGenerator(ASN1ObjectIdentifier kekAlgorithm, char[] password)
+ {
+ super(kekAlgorithm, password);
+ }
+
+ protected byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
+ throws CMSException
+ {
+ PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters());
+
+ PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
+
+ gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue());
+
+ return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey();
+ }
+
+ 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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/BcRSAKeyTransEnvelopedRecipient.java b/pkix/src/main/java/org/spongycastle/cms/bc/BcRSAKeyTransEnvelopedRecipient.java
new file mode 100644
index 00000000..601de841
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/BcRSAKeyTransEnvelopedRecipient.java
@@ -0,0 +1,50 @@
+package org.spongycastle.cms.bc;
+
+import java.io.InputStream;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.RecipientOperator;
+import org.spongycastle.crypto.BufferedBlockCipher;
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.StreamCipher;
+import org.spongycastle.crypto.io.CipherInputStream;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.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);
+ }
+ }
+ });
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/BcRSAKeyTransRecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/bc/BcRSAKeyTransRecipientInfoGenerator.java
new file mode 100644
index 00000000..09f7f8d0
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/BcRSAKeyTransRecipientInfoGenerator.java
@@ -0,0 +1,23 @@
+package org.spongycastle.cms.bc;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/BcRSASignerInfoVerifierBuilder.java b/pkix/src/main/java/org/spongycastle/cms/bc/BcRSASignerInfoVerifierBuilder.java
new file mode 100644
index 00000000..26028e1a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/BcRSASignerInfoVerifierBuilder.java
@@ -0,0 +1,39 @@
+package org.spongycastle.cms.bc;
+
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cms.CMSSignatureAlgorithmNameGenerator;
+import org.spongycastle.cms.SignerInformationVerifier;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.operator.DigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.SignatureAlgorithmIdentifierFinder;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/CMSUtils.java b/pkix/src/main/java/org/spongycastle/cms/bc/CMSUtils.java
new file mode 100644
index 00000000..90035ec1
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/CMSUtils.java
@@ -0,0 +1,23 @@
+package org.spongycastle.cms.bc;
+
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.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");
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/bc/EnvelopedDataHelper.java b/pkix/src/main/java/org/spongycastle/cms/bc/EnvelopedDataHelper.java
new file mode 100644
index 00000000..db65fd09
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/bc/EnvelopedDataHelper.java
@@ -0,0 +1,378 @@
+package org.spongycastle.cms.bc;
+
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1Null;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.spongycastle.asn1.misc.CAST5CBCParameters;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RC2CBCParameter;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.crypto.BlockCipher;
+import org.spongycastle.crypto.BufferedBlockCipher;
+import org.spongycastle.crypto.CipherKeyGenerator;
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.KeyGenerationParameters;
+import org.spongycastle.crypto.StreamCipher;
+import org.spongycastle.crypto.Wrapper;
+import org.spongycastle.crypto.engines.AESEngine;
+import org.spongycastle.crypto.engines.DESEngine;
+import org.spongycastle.crypto.engines.DESedeEngine;
+import org.spongycastle.crypto.engines.RC2Engine;
+import org.spongycastle.crypto.engines.RC4Engine;
+import org.spongycastle.crypto.engines.RFC3211WrapEngine;
+import org.spongycastle.crypto.generators.DESKeyGenerator;
+import org.spongycastle.crypto.generators.DESedeKeyGenerator;
+import org.spongycastle.crypto.modes.CBCBlockCipher;
+import org.spongycastle.crypto.paddings.PKCS7Padding;
+import org.spongycastle.crypto.paddings.PaddedBufferedBlockCipher;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.crypto.params.ParametersWithIV;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/CMSUtils.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/CMSUtils.java
new file mode 100644
index 00000000..9337a424
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/CMSUtils.java
@@ -0,0 +1,99 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.Provider;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.cms.IssuerAndSerialNumber;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.TBSCertificateStructure;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.jcajce.util.JcaJceUtils;
+
+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(Extension.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());
+ }
+ }
+
+ static ASN1Encodable extractParameters(AlgorithmParameters params)
+ throws CMSException
+ {
+ try
+ {
+ return JcaJceUtils.extractParameters(params);
+ }
+ catch (IOException e)
+ {
+ throw new CMSException("cannot extract parameters: " + e.getMessage(), e);
+ }
+ }
+
+ static void loadParameters(AlgorithmParameters params, ASN1Encodable sParams)
+ throws CMSException
+ {
+ try
+ {
+ JcaJceUtils.loadParameters(params, sParams);
+ }
+ catch (IOException e)
+ {
+ throw new CMSException("error encoding algorithm parameters.", e);
+ }
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/DefaultJcaJceExtHelper.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/DefaultJcaJceExtHelper.java
new file mode 100644
index 00000000..1285ff07
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/DefaultJcaJceExtHelper.java
@@ -0,0 +1,26 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.PrivateKey;
+
+import javax.crypto.SecretKey;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.operator.SymmetricKeyUnwrapper;
+import org.spongycastle.operator.jcajce.JceAsymmetricKeyUnwrapper;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/EnvelopedDataHelper.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/EnvelopedDataHelper.java
new file mode 100644
index 00000000..93de500e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/EnvelopedDataHelper.java
@@ -0,0 +1,668 @@
+package org.spongycastle.cms.jcajce;
+
+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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Null;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RC2CBCParameter;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.cms.CMSEnvelopedDataGenerator;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DefaultSecretKeySizeProvider;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.SecretKeySizeProvider;
+import org.spongycastle.operator.SymmetricKeyUnwrapper;
+import org.spongycastle.operator.jcajce.JceAsymmetricKeyUnwrapper;
+
+public class EnvelopedDataHelper
+{
+ protected static final SecretKeySizeProvider KEY_SIZE_PROVIDER = DefaultSecretKeySizeProvider.INSTANCE;
+
+ 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");
+ BASE_CIPHER_NAMES.put(PKCSObjectIdentifiers.rc4, "RC4");
+
+ CIPHER_ALG_NAMES.put(CMSAlgorithm.DES_CBC, "DES/CBC/PKCS5Padding");
+ CIPHER_ALG_NAMES.put(CMSAlgorithm.RC2_CBC, "RC2/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");
+ CIPHER_ALG_NAMES.put(PKCSObjectIdentifiers.rc4, "RC4");
+
+ 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");
+ }
+
+ public 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");
+ }
+
+ public void keySizeCheck(AlgorithmIdentifier keyAlgorithm, Key key)
+ throws CMSException
+ {
+ int expectedKeySize = EnvelopedDataHelper.KEY_SIZE_PROVIDER.getKeySize(keyAlgorithm);
+ if (expectedKeySize > 0)
+ {
+ byte[] keyEnc = null;
+
+ try
+ {
+ keyEnc = key.getEncoded();
+ }
+ catch (Exception e)
+ {
+ // ignore - we're using a HSM...
+ }
+
+ if (keyEnc != null)
+ {
+ if (keyEnc.length * 8 != expectedKeySize)
+ {
+ throw new CMSException("Expected key size for algorithm OID not found in recipient.");
+ }
+ }
+ }
+ }
+
+ 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());
+ }
+
+ public 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());
+
+ CMSUtils.loadParameters(params, sParams);
+
+ 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());
+
+ CMSUtils.loadParameters(params, sParams);
+
+ 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(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 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)
+ {
+ asn1Params = CMSUtils.extractParameters(params);
+ }
+ 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaJceExtHelper.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaJceExtHelper.java
new file mode 100644
index 00000000..e29f1bd9
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaJceExtHelper.java
@@ -0,0 +1,18 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.PrivateKey;
+
+import javax.crypto.SecretKey;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.operator.SymmetricKeyUnwrapper;
+import org.spongycastle.operator.jcajce.JceAsymmetricKeyUnwrapper;
+
+public interface JcaJceExtHelper
+ extends JcaJceHelper
+{
+ JceAsymmetricKeyUnwrapper createAsymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, PrivateKey keyEncryptionKey);
+
+ SymmetricKeyUnwrapper createSymmetricUnwrapper(AlgorithmIdentifier keyEncryptionAlgorithm, SecretKey keyEncryptionKey);
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSelectorConverter.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSelectorConverter.java
new file mode 100644
index 00000000..6dc5c9a8
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSelectorConverter.java
@@ -0,0 +1,55 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.IOException;
+import java.security.cert.X509CertSelector;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cms.KeyTransRecipientId;
+import org.spongycastle.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());
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSignerId.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSignerId.java
new file mode 100644
index 00000000..27934bf6
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSignerId.java
@@ -0,0 +1,56 @@
+package org.spongycastle.cms.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
new file mode 100644
index 00000000..79ad9070
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
@@ -0,0 +1,68 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.spongycastle.cms.CMSAttributeTableGenerator;
+import org.spongycastle.cms.SignerInfoGenerator;
+import org.spongycastle.cms.SignerInfoGeneratorBuilder;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.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));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java
new file mode 100644
index 00000000..c5077819
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java
@@ -0,0 +1,180 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cms.CMSSignatureAlgorithmNameGenerator;
+import org.spongycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator;
+import org.spongycastle.cms.SignerInformationVerifier;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.SignatureAlgorithmIdentifierFinder;
+import org.spongycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSimpleSignerInfoGeneratorBuilder.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSimpleSignerInfoGeneratorBuilder.java
new file mode 100644
index 00000000..87aca5c7
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSimpleSignerInfoGeneratorBuilder.java
@@ -0,0 +1,202 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.spongycastle.cms.CMSAttributeTableGenerator;
+import org.spongycastle.cms.DefaultSignedAttributeTableGenerator;
+import org.spongycastle.cms.SignerInfoGenerator;
+import org.spongycastle.cms.SignerInfoGeneratorBuilder;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.spongycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
+
+/**
+ * Use this class if you are using a provider that has all the facilities you
+ * need.
+ * <p>
+ * For example:
+ * <pre>
+ * CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
+ * ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("SC").build(signKP.getPrivate());
+ *
+ * gen.addSignerInfoGenerator(
+ * new JcaSignerInfoGeneratorBuilder(
+ * new JcaDigestCalculatorProviderBuilder().setProvider("SC").build())
+ * .build(sha1Signer, signCert));
+ * </pre>
+ * becomes:
+ * <pre>
+ * CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
+ *
+ * gen.addSignerInfoGenerator(
+ * new JcaSimpleSignerInfoGeneratorBuilder()
+ * .setProvider("SC")
+ * .build("SHA1withRSA", signKP.getPrivate(), signCert));
+ * </pre>
+ */
+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();
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java
new file mode 100644
index 00000000..4463b065
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java
@@ -0,0 +1,150 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator;
+import org.spongycastle.cms.SignerInformationVerifier;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java
new file mode 100644
index 00000000..ceb138ed
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java
@@ -0,0 +1,24 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.cert.X509CertSelector;
+
+import org.spongycastle.cms.KeyTransRecipientId;
+import org.spongycastle.cms.SignerId;
+
+public class JcaX509CertSelectorConverter
+ extends org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceAlgorithmIdentifierConverter.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceAlgorithmIdentifierConverter.java
new file mode 100644
index 00000000..32007919
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceAlgorithmIdentifierConverter.java
@@ -0,0 +1,64 @@
+package org.spongycastle.cms.jcajce;
+
+
+import java.security.AlgorithmParameters;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.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());
+
+ CMSUtils.loadParameters(params, algorithmIdentifier.getParameters());
+
+ return params;
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new CMSException("can't find parameters for algorithm", e);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new CMSException("can't find provider for algorithm", e);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
new file mode 100644
index 00000000..5711df3d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
@@ -0,0 +1,160 @@
+package org.spongycastle.cms.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DefaultSecretKeySizeProvider;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.operator.SecretKeySizeProvider;
+import org.spongycastle.operator.jcajce.JceGenericKey;
+
+public class JceCMSContentEncryptorBuilder
+{
+ private static final SecretKeySizeProvider KEY_SIZE_PROVIDER = DefaultSecretKeySizeProvider.INSTANCE;
+
+
+ private final ASN1ObjectIdentifier encryptionOID;
+ private final int keySize;
+
+ private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper());
+ private SecureRandom random;
+
+ public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID)
+ {
+ this(encryptionOID, KEY_SIZE_PROVIDER.getKeySize(encryptionOID));
+ }
+
+ public JceCMSContentEncryptorBuilder(ASN1ObjectIdentifier encryptionOID, int keySize)
+ {
+ this.encryptionOID = encryptionOID;
+ this.keySize = keySize;
+
+ int fixedSize = KEY_SIZE_PROVIDER.getKeySize(encryptionOID);
+
+ if (encryptionOID.equals(PKCSObjectIdentifiers.des_EDE3_CBC))
+ {
+ if (keySize != 168 && keySize != fixedSize)
+ {
+ throw new IllegalArgumentException("incorrect keySize for encryptionOID passed to builder.");
+ }
+ }
+ else
+ {
+ if (fixedSize > 0 && fixedSize != keySize)
+ {
+ throw new IllegalArgumentException("incorrect keySize for encryptionOID passed to builder.");
+ }
+ }
+ }
+
+ 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
+ {
+ if (encryptionOID.equals(PKCSObjectIdentifiers.des_EDE3_CBC) && keySize == 192)
+ {
+ keySize = 168;
+ }
+ 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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java
new file mode 100644
index 00000000..d6097471
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java
@@ -0,0 +1,155 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.jcajce.io.MacOutputStream;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.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;
+ }
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKAuthenticatedRecipient.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKAuthenticatedRecipient.java
new file mode 100644
index 00000000..55a19d54
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKAuthenticatedRecipient.java
@@ -0,0 +1,61 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.OutputStream;
+import java.security.Key;
+
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.RecipientOperator;
+import org.spongycastle.jcajce.io.MacOutputStream;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.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();
+ }
+ });
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKEnvelopedRecipient.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKEnvelopedRecipient.java
new file mode 100644
index 00000000..8bf94006
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKEnvelopedRecipient.java
@@ -0,0 +1,43 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.InputStream;
+import java.security.Key;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.SecretKey;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.RecipientOperator;
+import org.spongycastle.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);
+ }
+ });
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKRecipient.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKRecipient.java
new file mode 100644
index 00000000..84ad638f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKRecipient.java
@@ -0,0 +1,119 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.Key;
+import java.security.Provider;
+
+import javax.crypto.SecretKey;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.KEKRecipient;
+import org.spongycastle.operator.OperatorException;
+import org.spongycastle.operator.SymmetricKeyUnwrapper;
+
+public abstract class JceKEKRecipient
+ implements KEKRecipient
+{
+ private SecretKey recipientKey;
+
+ protected EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper());
+ protected EnvelopedDataHelper contentHelper = helper;
+ protected boolean validateKeySize = false;
+
+ 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;
+ }
+
+ /**
+ * Set validation of retrieved key sizes against the algorithm parameters for the encrypted key where possible - default is off.
+ * <p>
+ * This setting will not have any affect if the encryption algorithm in the recipient does not specify a particular key size, or
+ * if the unwrapper is a HSM and the byte encoding of the unwrapped secret key is not available.
+ * </p>
+ * @param doValidate true if unwrapped key's should be validated against the content encryption algorithm, false otherwise.
+ * @return this recipient.
+ */
+ public JceKEKRecipient setKeySizeValidation(boolean doValidate)
+ {
+ this.validateKeySize = doValidate;
+
+ return this;
+ }
+
+ protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier encryptedKeyAlgorithm, byte[] encryptedContentEncryptionKey)
+ throws CMSException
+ {
+ SymmetricKeyUnwrapper unwrapper = helper.createSymmetricUnwrapper(keyEncryptionAlgorithm, recipientKey);
+
+ try
+ {
+ Key key = helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedContentEncryptionKey));
+
+ if (validateKeySize)
+ {
+ helper.keySizeCheck(encryptedKeyAlgorithm, key);
+ }
+
+ return key;
+ }
+ catch (OperatorException e)
+ {
+ throw new CMSException("exception unwrapping key: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKRecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKRecipientInfoGenerator.java
new file mode 100644
index 00000000..7a67de4a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKEKRecipientInfoGenerator.java
@@ -0,0 +1,45 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.Provider;
+import java.security.SecureRandom;
+
+import javax.crypto.SecretKey;
+
+import org.spongycastle.asn1.cms.KEKIdentifier;
+import org.spongycastle.cms.KEKRecipientInfoGenerator;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeAuthenticatedRecipient.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeAuthenticatedRecipient.java
new file mode 100644
index 00000000..3186b561
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeAuthenticatedRecipient.java
@@ -0,0 +1,57 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.PrivateKey;
+
+import javax.crypto.Mac;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.RecipientOperator;
+import org.spongycastle.jcajce.io.MacOutputStream;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.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();
+ }
+ });
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeEnvelopedRecipient.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeEnvelopedRecipient.java
new file mode 100644
index 00000000..274d8ed9
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeEnvelopedRecipient.java
@@ -0,0 +1,45 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.InputStream;
+import java.security.Key;
+import java.security.PrivateKey;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.RecipientOperator;
+import org.spongycastle.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);
+ }
+ });
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeRecipient.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeRecipient.java
new file mode 100644
index 00000000..1beea382
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeRecipient.java
@@ -0,0 +1,184 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.cms.ecc.MQVuserKeyingMaterial;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cms.CMSEnvelopedGenerator;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.KeyAgreeRecipient;
+import org.spongycastle.jce.spec.MQVPrivateKeySpec;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java
new file mode 100644
index 00000000..1774b394
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java
@@ -0,0 +1,23 @@
+package org.spongycastle.cms.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java
new file mode 100644
index 00000000..eb9699f5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java
@@ -0,0 +1,215 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.cms.KeyAgreeRecipientIdentifier;
+import org.spongycastle.asn1.cms.RecipientEncryptedKey;
+import org.spongycastle.asn1.cms.RecipientKeyIdentifier;
+import org.spongycastle.asn1.cms.ecc.MQVuserKeyingMaterial;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.cms.CMSEnvelopedGenerator;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.KeyAgreeRecipientInfoGenerator;
+import org.spongycastle.jce.spec.MQVPrivateKeySpec;
+import org.spongycastle.jce.spec.MQVPublicKeySpec;
+import org.spongycastle.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);
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransAuthenticatedRecipient.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransAuthenticatedRecipient.java
new file mode 100644
index 00000000..31b38303
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransAuthenticatedRecipient.java
@@ -0,0 +1,60 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.PrivateKey;
+
+import javax.crypto.Mac;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.RecipientOperator;
+import org.spongycastle.jcajce.io.MacOutputStream;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.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();
+ }
+ });
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransEnvelopedRecipient.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransEnvelopedRecipient.java
new file mode 100644
index 00000000..8ccc6bf7
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransEnvelopedRecipient.java
@@ -0,0 +1,43 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.InputStream;
+import java.security.Key;
+import java.security.PrivateKey;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.RecipientOperator;
+import org.spongycastle.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);
+ }
+ });
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransRecipient.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransRecipient.java
new file mode 100644
index 00000000..e3939611
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransRecipient.java
@@ -0,0 +1,156 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.KeyTransRecipient;
+import org.spongycastle.operator.OperatorException;
+import org.spongycastle.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();
+ protected boolean validateKeySize = false;
+
+ 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.
+ * <p>
+ * For example:
+ * <pre>
+ * unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ * </pre>
+ * </p>
+ * @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;
+ }
+
+ /**
+ * Set validation of retrieved key sizes against the algorithm parameters for the encrypted key where possible - default is off.
+ * <p>
+ * This setting will not have any affect if the encryption algorithm in the recipient does not specify a particular key size, or
+ * if the unwrapper is a HSM and the byte encoding of the unwrapped secret key is not available.
+ * </p>
+ * @param doValidate true if unwrapped key's should be validated against the content encryption algorithm, false otherwise.
+ * @return this recipient.
+ */
+ public JceKeyTransRecipient setKeySizeValidation(boolean doValidate)
+ {
+ this.validateKeySize = doValidate;
+
+ 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
+ {
+ Key key = helper.getJceKey(encryptedKeyAlgorithm.getAlgorithm(), unwrapper.generateUnwrappedKey(encryptedKeyAlgorithm, encryptedEncryptionKey));
+
+ if (validateKeySize)
+ {
+ helper.keySizeCheck(encryptedKeyAlgorithm, key);
+ }
+
+ return key;
+ }
+ catch (OperatorException e)
+ {
+ throw new CMSException("exception unwrapping key: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java
new file mode 100644
index 00000000..62ce1fea
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java
@@ -0,0 +1,57 @@
+package org.spongycastle.cms.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransRecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransRecipientInfoGenerator.java
new file mode 100644
index 00000000..c3cf5693
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JceKeyTransRecipientInfoGenerator.java
@@ -0,0 +1,87 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cms.IssuerAndSerialNumber;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.spongycastle.cms.KeyTransRecipientInfoGenerator;
+import org.spongycastle.operator.jcajce.JceAsymmetricKeyWrapper;
+
+public class JceKeyTransRecipientInfoGenerator
+ extends KeyTransRecipientInfoGenerator
+{
+ public JceKeyTransRecipientInfoGenerator(X509Certificate recipientCert)
+ throws CertificateEncodingException
+ {
+ super(new IssuerAndSerialNumber(new JcaX509CertificateHolder(recipientCert).toASN1Structure()), new JceAsymmetricKeyWrapper(recipientCert));
+ }
+
+ public JceKeyTransRecipientInfoGenerator(byte[] subjectKeyIdentifier, PublicKey publicKey)
+ {
+ super(subjectKeyIdentifier, new JceAsymmetricKeyWrapper(publicKey));
+ }
+
+ /**
+ * Create a generator overriding the algorithm type implied by the public key in the certificate passed in.
+ *
+ * @param recipientCert certificate carrying the public key.
+ * @param algorithmIdentifier the identifier and parameters for the encryption algorithm to be used.
+ */
+ public JceKeyTransRecipientInfoGenerator(X509Certificate recipientCert, AlgorithmIdentifier algorithmIdentifier)
+ throws CertificateEncodingException
+ {
+ super(new IssuerAndSerialNumber(new JcaX509CertificateHolder(recipientCert).toASN1Structure()), new JceAsymmetricKeyWrapper(algorithmIdentifier, recipientCert.getPublicKey()));
+ }
+
+ /**
+ * Create a generator overriding the algorithm type implied by the public key passed in.
+ *
+ * @param subjectKeyIdentifier the subject key identifier value to associate with the public key.
+ * @param algorithmIdentifier the identifier and parameters for the encryption algorithm to be used.
+ * @param publicKey the public key to use.
+ */
+ public JceKeyTransRecipientInfoGenerator(byte[] subjectKeyIdentifier, AlgorithmIdentifier algorithmIdentifier, PublicKey publicKey)
+ {
+ super(subjectKeyIdentifier, new JceAsymmetricKeyWrapper(algorithmIdentifier, 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.
+ * <p>
+ * For example:
+ * <pre>
+ * unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ * </pre>
+ * </p>
+ * @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;
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordAuthenticatedRecipient.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordAuthenticatedRecipient.java
new file mode 100644
index 00000000..12b8c362
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordAuthenticatedRecipient.java
@@ -0,0 +1,54 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.OutputStream;
+import java.security.Key;
+
+import javax.crypto.Mac;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.RecipientOperator;
+import org.spongycastle.jcajce.io.MacOutputStream;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.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();
+ }
+ });
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordEnvelopedRecipient.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordEnvelopedRecipient.java
new file mode 100644
index 00000000..e46c8ddb
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordEnvelopedRecipient.java
@@ -0,0 +1,42 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.InputStream;
+import java.security.Key;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.RecipientOperator;
+import org.spongycastle.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);
+ }
+ });
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordRecipient.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordRecipient.java
new file mode 100644
index 00000000..b70651b1
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordRecipient.java
@@ -0,0 +1,97 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.PasswordRecipient;
+import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
+import org.spongycastle.crypto.params.KeyParameter;
+
+/**
+ * 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 byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
+ throws CMSException
+ {
+ PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters());
+
+ PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
+
+ gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue());
+
+ return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey();
+ }
+
+ public int getPasswordConversionScheme()
+ {
+ return schemeID;
+ }
+
+ public char[] getPassword()
+ {
+ return password;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java
new file mode 100644
index 00000000..d29fbab3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java
@@ -0,0 +1,76 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.PasswordRecipientInfoGenerator;
+import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.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;
+ }
+
+ protected byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
+ throws CMSException
+ {
+ PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters());
+
+ PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
+
+ gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue());
+
+ return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey();
+ }
+
+ 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);
+ }
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/NamedJcaJceExtHelper.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/NamedJcaJceExtHelper.java
new file mode 100644
index 00000000..c5589320
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/NamedJcaJceExtHelper.java
@@ -0,0 +1,31 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.PrivateKey;
+
+import javax.crypto.SecretKey;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.operator.SymmetricKeyUnwrapper;
+import org.spongycastle.operator.jcajce.JceAsymmetricKeyUnwrapper;
+import org.spongycastle.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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/ProviderJcaJceExtHelper.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/ProviderJcaJceExtHelper.java
new file mode 100644
index 00000000..25075a1f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/ProviderJcaJceExtHelper.java
@@ -0,0 +1,32 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.PrivateKey;
+import java.security.Provider;
+
+import javax.crypto.SecretKey;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.SymmetricKeyUnwrapper;
+import org.spongycastle.operator.jcajce.JceAsymmetricKeyUnwrapper;
+import org.spongycastle.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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/ZlibCompressor.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/ZlibCompressor.java
new file mode 100644
index 00000000..a4787f45
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/ZlibCompressor.java
@@ -0,0 +1,24 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.OutputStream;
+import java.util.zip.DeflaterOutputStream;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/cms/jcajce/ZlibExpanderProvider.java b/pkix/src/main/java/org/spongycastle/cms/jcajce/ZlibExpanderProvider.java
new file mode 100644
index 00000000..adc01206
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/cms/jcajce/ZlibExpanderProvider.java
@@ -0,0 +1,116 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.InflaterInputStream;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.InputExpander;
+import org.spongycastle.operator.InputExpanderProvider;
+import org.spongycastle.util.io.StreamOverflowException;
+
+public class ZlibExpanderProvider
+ implements InputExpanderProvider
+{
+ private final long limit;
+
+ /**
+ * Base constructor. Create an expander which will not limit the size of any objects expanded in the stream.
+ */
+ 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;
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/CCPDRequestBuilder.java b/pkix/src/main/java/org/spongycastle/dvcs/CCPDRequestBuilder.java
new file mode 100644
index 00000000..e48dd2a3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/CCPDRequestBuilder.java
@@ -0,0 +1,32 @@
+package org.spongycastle.dvcs;
+
+import org.spongycastle.asn1.dvcs.DVCSRequestInformationBuilder;
+import org.spongycastle.asn1.dvcs.Data;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/CCPDRequestData.java b/pkix/src/main/java/org/spongycastle/dvcs/CCPDRequestData.java
new file mode 100644
index 00000000..202dd774
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/CCPDRequestData.java
@@ -0,0 +1,48 @@
+package org.spongycastle.dvcs;
+
+import org.spongycastle.asn1.dvcs.Data;
+
+/**
+ * Data piece of DVCRequest for CCPD service (Certify Claim of Possession of Data).
+ * It contains CCPD-specific selector interface.
+ * <p/>
+ * 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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/CPDRequestBuilder.java b/pkix/src/main/java/org/spongycastle/dvcs/CPDRequestBuilder.java
new file mode 100644
index 00000000..0b0b8189
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/CPDRequestBuilder.java
@@ -0,0 +1,34 @@
+package org.spongycastle.dvcs;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.dvcs.DVCSRequestInformationBuilder;
+import org.spongycastle.asn1.dvcs.Data;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/CPDRequestData.java b/pkix/src/main/java/org/spongycastle/dvcs/CPDRequestData.java
new file mode 100644
index 00000000..a7c1f5a8
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/CPDRequestData.java
@@ -0,0 +1,40 @@
+package org.spongycastle.dvcs;
+
+import org.spongycastle.asn1.dvcs.Data;
+
+/**
+ * Data piece of DVCRequest for CPD service (Certify Possession of Data).
+ * It contains CPD-specific selector interface.
+ * <p/>
+ * 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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/DVCSConstructionException.java b/pkix/src/main/java/org/spongycastle/dvcs/DVCSConstructionException.java
new file mode 100644
index 00000000..73e6b0dc
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/DVCSConstructionException.java
@@ -0,0 +1,20 @@
+package org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/DVCSException.java b/pkix/src/main/java/org/spongycastle/dvcs/DVCSException.java
new file mode 100644
index 00000000..5aa8f51e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/DVCSException.java
@@ -0,0 +1,28 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/DVCSMessage.java b/pkix/src/main/java/org/spongycastle/dvcs/DVCSMessage.java
new file mode 100644
index 00000000..6758f359
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/DVCSMessage.java
@@ -0,0 +1,22 @@
+package org.spongycastle.dvcs;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.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();
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/DVCSParsingException.java b/pkix/src/main/java/org/spongycastle/dvcs/DVCSParsingException.java
new file mode 100644
index 00000000..e1452576
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/DVCSParsingException.java
@@ -0,0 +1,20 @@
+package org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/DVCSRequest.java b/pkix/src/main/java/org/spongycastle/dvcs/DVCSRequest.java
new file mode 100644
index 00000000..f8658ab5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/DVCSRequest.java
@@ -0,0 +1,134 @@
+package org.spongycastle.dvcs;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.SignedData;
+import org.spongycastle.asn1.dvcs.DVCSObjectIdentifiers;
+import org.spongycastle.asn1.dvcs.ServiceType;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.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.spongycastle.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.spongycastle.asn1.dvcs.DVCSRequest.getInstance(contentInfo.getContent());
+ }
+ else
+ {
+ this.asn1 = org.spongycastle.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.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/DVCSRequestBuilder.java b/pkix/src/main/java/org/spongycastle/dvcs/DVCSRequestBuilder.java
new file mode 100644
index 00000000..f1982b91
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/DVCSRequestBuilder.java
@@ -0,0 +1,131 @@
+package org.spongycastle.dvcs;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.dvcs.DVCSObjectIdentifiers;
+import org.spongycastle.asn1.dvcs.DVCSRequestInformationBuilder;
+import org.spongycastle.asn1.dvcs.Data;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.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.spongycastle.asn1.dvcs.DVCSRequest request = new org.spongycastle.asn1.dvcs.DVCSRequest(requestInformationBuilder.build(), data);
+
+ return new DVCSRequest(new ContentInfo(DVCSObjectIdentifiers.id_ct_DVCSRequestData, request));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/DVCSRequestData.java b/pkix/src/main/java/org/spongycastle/dvcs/DVCSRequestData.java
new file mode 100644
index 00000000..35cdd325
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/DVCSRequestData.java
@@ -0,0 +1,38 @@
+package org.spongycastle.dvcs;
+
+import org.spongycastle.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.
+ * <p/>
+ * 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/DVCSRequestInfo.java b/pkix/src/main/java/org/spongycastle/dvcs/DVCSRequestInfo.java
new file mode 100644
index 00000000..1f51e3e6
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/DVCSRequestInfo.java
@@ -0,0 +1,237 @@
+package org.spongycastle.dvcs;
+
+import java.math.BigInteger;
+import java.util.Date;
+
+import org.spongycastle.asn1.dvcs.DVCSRequestInformation;
+import org.spongycastle.asn1.dvcs.DVCSTime;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.PolicyInformation;
+import org.spongycastle.tsp.TimeStampToken;
+import org.spongycastle.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));
+ }
+}
+
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/DVCSResponse.java b/pkix/src/main/java/org/spongycastle/dvcs/DVCSResponse.java
new file mode 100644
index 00000000..f7185519
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/DVCSResponse.java
@@ -0,0 +1,74 @@
+package org.spongycastle.dvcs;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.SignedData;
+import org.spongycastle.asn1.dvcs.DVCSObjectIdentifiers;
+import org.spongycastle.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.spongycastle.asn1.dvcs.DVCSResponse asn1;
+
+ /**
+ * Constructs DVCRequest from CMS SignedData object.
+ *
+ * @param signedData the CMS SignedData object containing the request
+ * @throws org.spongycastle.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.spongycastle.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.spongycastle.asn1.dvcs.DVCSResponse.getInstance(contentInfo.getContent());
+ }
+ else
+ {
+ this.asn1 = org.spongycastle.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.spongycastle.asn1.dvcs.DVCSResponse object.
+ */
+ public ASN1Encodable getContent()
+ {
+ return asn1;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/MessageImprint.java b/pkix/src/main/java/org/spongycastle/dvcs/MessageImprint.java
new file mode 100644
index 00000000..c9793880
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/MessageImprint.java
@@ -0,0 +1,38 @@
+package org.spongycastle.dvcs;
+
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/MessageImprintBuilder.java b/pkix/src/main/java/org/spongycastle/dvcs/MessageImprintBuilder.java
new file mode 100644
index 00000000..f7dc987e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/MessageImprintBuilder.java
@@ -0,0 +1,35 @@
+package org.spongycastle.dvcs;
+
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.x509.DigestInfo;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/SignedDVCSMessageGenerator.java b/pkix/src/main/java/org/spongycastle/dvcs/SignedDVCSMessageGenerator.java
new file mode 100644
index 00000000..2378bcf2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/SignedDVCSMessageGenerator.java
@@ -0,0 +1,45 @@
+package org.spongycastle.dvcs;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.CMSProcessableByteArray;
+import org.spongycastle.cms.CMSSignedData;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/TargetChain.java b/pkix/src/main/java/org/spongycastle/dvcs/TargetChain.java
new file mode 100644
index 00000000..d45714f3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/TargetChain.java
@@ -0,0 +1,18 @@
+package org.spongycastle.dvcs;
+
+import org.spongycastle.asn1.dvcs.TargetEtcChain;
+
+public class TargetChain
+{
+ private final TargetEtcChain certs;
+
+ public TargetChain(TargetEtcChain certs)
+ {
+ this.certs = certs;
+ }
+
+ public TargetEtcChain toASN1Structure()
+ {
+ return certs;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/VPKCRequestBuilder.java b/pkix/src/main/java/org/spongycastle/dvcs/VPKCRequestBuilder.java
new file mode 100644
index 00000000..9a68b7d3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/VPKCRequestBuilder.java
@@ -0,0 +1,76 @@
+package org.spongycastle.dvcs;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.spongycastle.asn1.dvcs.CertEtcToken;
+import org.spongycastle.asn1.dvcs.DVCSRequestInformationBuilder;
+import org.spongycastle.asn1.dvcs.DVCSTime;
+import org.spongycastle.asn1.dvcs.Data;
+import org.spongycastle.asn1.dvcs.ServiceType;
+import org.spongycastle.asn1.dvcs.TargetEtcChain;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/VPKCRequestData.java b/pkix/src/main/java/org/spongycastle/dvcs/VPKCRequestData.java
new file mode 100644
index 00000000..561f93bf
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/VPKCRequestData.java
@@ -0,0 +1,51 @@
+package org.spongycastle.dvcs;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.spongycastle.asn1.dvcs.Data;
+import org.spongycastle.asn1.dvcs.TargetEtcChain;
+
+/**
+ * Data piece of DVCS request to VPKC service (Verify Public Key Certificates).
+ * It contains VPKC-specific interface.
+ * <p/>
+ * 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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/VSDRequestBuilder.java b/pkix/src/main/java/org/spongycastle/dvcs/VSDRequestBuilder.java
new file mode 100644
index 00000000..f2f7df54
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/VSDRequestBuilder.java
@@ -0,0 +1,49 @@
+package org.spongycastle.dvcs;
+
+import java.io.IOException;
+import java.util.Date;
+
+import org.spongycastle.asn1.dvcs.DVCSRequestInformationBuilder;
+import org.spongycastle.asn1.dvcs.DVCSTime;
+import org.spongycastle.asn1.dvcs.Data;
+import org.spongycastle.asn1.dvcs.ServiceType;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/dvcs/VSDRequestData.java b/pkix/src/main/java/org/spongycastle/dvcs/VSDRequestData.java
new file mode 100644
index 00000000..21adaa3f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/dvcs/VSDRequestData.java
@@ -0,0 +1,66 @@
+package org.spongycastle.dvcs;
+
+import org.spongycastle.asn1.dvcs.Data;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.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.
+ * <p/>
+ * 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/EACCertificateBuilder.java b/pkix/src/main/java/org/spongycastle/eac/EACCertificateBuilder.java
new file mode 100644
index 00000000..b3ca48e8
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/EACCertificateBuilder.java
@@ -0,0 +1,83 @@
+package org.spongycastle.eac;
+
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.DERApplicationSpecific;
+import org.spongycastle.asn1.eac.CVCertificate;
+import org.spongycastle.asn1.eac.CertificateBody;
+import org.spongycastle.asn1.eac.CertificateHolderAuthorization;
+import org.spongycastle.asn1.eac.CertificateHolderReference;
+import org.spongycastle.asn1.eac.CertificationAuthorityReference;
+import org.spongycastle.asn1.eac.EACTags;
+import org.spongycastle.asn1.eac.PackedDate;
+import org.spongycastle.asn1.eac.PublicKeyDataObject;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/EACCertificateHolder.java b/pkix/src/main/java/org/spongycastle/eac/EACCertificateHolder.java
new file mode 100644
index 00000000..edc75a6d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/EACCertificateHolder.java
@@ -0,0 +1,88 @@
+package org.spongycastle.eac;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1ParsingException;
+import org.spongycastle.asn1.eac.CVCertificate;
+import org.spongycastle.asn1.eac.PublicKeyDataObject;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/EACCertificateRequestHolder.java b/pkix/src/main/java/org/spongycastle/eac/EACCertificateRequestHolder.java
new file mode 100644
index 00000000..77b01e4d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/EACCertificateRequestHolder.java
@@ -0,0 +1,88 @@
+package org.spongycastle.eac;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1ParsingException;
+import org.spongycastle.asn1.eac.CVCertificateRequest;
+import org.spongycastle.asn1.eac.PublicKeyDataObject;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/EACException.java b/pkix/src/main/java/org/spongycastle/eac/EACException.java
new file mode 100644
index 00000000..d8e1612a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/EACException.java
@@ -0,0 +1,27 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/EACIOException.java b/pkix/src/main/java/org/spongycastle/eac/EACIOException.java
new file mode 100644
index 00000000..857a6f6a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/EACIOException.java
@@ -0,0 +1,29 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/jcajce/DefaultEACHelper.java b/pkix/src/main/java/org/spongycastle/eac/jcajce/DefaultEACHelper.java
new file mode 100644
index 00000000..703e1405
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/jcajce/DefaultEACHelper.java
@@ -0,0 +1,14 @@
+package org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/jcajce/EACHelper.java b/pkix/src/main/java/org/spongycastle/eac/jcajce/EACHelper.java
new file mode 100644
index 00000000..c6f3ffb2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/jcajce/EACHelper.java
@@ -0,0 +1,11 @@
+package org.spongycastle.eac.jcajce;
+
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+
+interface EACHelper
+{
+ KeyFactory createKeyFactory(String type)
+ throws NoSuchProviderException, NoSuchAlgorithmException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/jcajce/JcaPublicKeyConverter.java b/pkix/src/main/java/org/spongycastle/eac/jcajce/JcaPublicKeyConverter.java
new file mode 100644
index 00000000..9e6a7eca
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/jcajce/JcaPublicKeyConverter.java
@@ -0,0 +1,168 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.eac.EACObjectIdentifiers;
+import org.spongycastle.asn1.eac.ECDSAPublicKey;
+import org.spongycastle.asn1.eac.PublicKeyDataObject;
+import org.spongycastle.asn1.eac.RSAPublicKey;
+import org.spongycastle.eac.EACException;
+import org.spongycastle.jce.spec.ECParameterSpec;
+import org.spongycastle.jce.spec.ECPublicKeySpec;
+import org.spongycastle.math.ec.ECCurve;
+import org.spongycastle.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.spongycastle.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!!!");
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/jcajce/NamedEACHelper.java b/pkix/src/main/java/org/spongycastle/eac/jcajce/NamedEACHelper.java
new file mode 100644
index 00000000..7e85142d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/jcajce/NamedEACHelper.java
@@ -0,0 +1,22 @@
+package org.spongycastle.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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/eac/jcajce/ProviderEACHelper.java b/pkix/src/main/java/org/spongycastle/eac/jcajce/ProviderEACHelper.java
new file mode 100644
index 00000000..2cda60a2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/jcajce/ProviderEACHelper.java
@@ -0,0 +1,22 @@
+package org.spongycastle.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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/eac/operator/EACSignatureVerifier.java b/pkix/src/main/java/org/spongycastle/eac/operator/EACSignatureVerifier.java
new file mode 100644
index 00000000..3dd967b9
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/operator/EACSignatureVerifier.java
@@ -0,0 +1,30 @@
+package org.spongycastle.eac.operator;
+
+import java.io.OutputStream;
+
+import org.spongycastle.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.spongycastle.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);
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/eac/operator/EACSigner.java b/pkix/src/main/java/org/spongycastle/eac/operator/EACSigner.java
new file mode 100644
index 00000000..9a53685a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/operator/EACSigner.java
@@ -0,0 +1,27 @@
+package org.spongycastle.eac.operator;
+
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+
+public interface EACSigner
+{
+ ASN1ObjectIdentifier getUsageIdentifier();
+
+ /**
+ * Returns a stream that will accept data for the purpose of calculating
+ * a signature. Use org.spongycastle.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();
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/DefaultEACHelper.java b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/DefaultEACHelper.java
new file mode 100644
index 00000000..3aab0585
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/DefaultEACHelper.java
@@ -0,0 +1,14 @@
+package org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/EACHelper.java b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/EACHelper.java
new file mode 100644
index 00000000..21369981
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/EACHelper.java
@@ -0,0 +1,39 @@
+package org.spongycastle.eac.operator.jcajce;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Signature;
+import java.util.Hashtable;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.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;
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/EACUtil.java b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/EACUtil.java
new file mode 100644
index 00000000..c21178a5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/EACUtil.java
@@ -0,0 +1,5 @@
+package org.spongycastle.eac.operator.jcajce;
+
+class EACUtil
+{
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/JcaEACSignatureVerifierBuilder.java b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/JcaEACSignatureVerifierBuilder.java
new file mode 100644
index 00000000..7ffdb79a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/JcaEACSignatureVerifierBuilder.java
@@ -0,0 +1,181 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.eac.EACObjectIdentifiers;
+import org.spongycastle.eac.operator.EACSignatureVerifier;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.OperatorStreamException;
+import org.spongycastle.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 ASN1Integer(new BigInteger(1, r)));
+ v.add(new ASN1Integer(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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/JcaEACSignerBuilder.java b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/JcaEACSignerBuilder.java
new file mode 100644
index 00000000..460bb5cf
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/JcaEACSignerBuilder.java
@@ -0,0 +1,234 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.eac.EACObjectIdentifiers;
+import org.spongycastle.eac.operator.EACSigner;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.OperatorStreamException;
+import org.spongycastle.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();
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/NamedEACHelper.java b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/NamedEACHelper.java
new file mode 100644
index 00000000..129356c2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/NamedEACHelper.java
@@ -0,0 +1,22 @@
+package org.spongycastle.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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java
new file mode 100644
index 00000000..e222dbdb
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java
@@ -0,0 +1,22 @@
+package org.spongycastle.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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/mozilla/SignedPublicKeyAndChallenge.java b/pkix/src/main/java/org/spongycastle/mozilla/SignedPublicKeyAndChallenge.java
new file mode 100644
index 00000000..3244663a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/mozilla/SignedPublicKeyAndChallenge.java
@@ -0,0 +1,139 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1Object;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.mozilla.PublicKeyAndChallenge;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+
+/**
+ * This is designed to parse the SignedPublicKeyAndChallenge created by the
+ * KEYGEN tag included by Mozilla based browsers.
+ * <pre>
+ * PublicKeyAndChallenge ::= SEQUENCE {
+ * spki SubjectPublicKeyInfo,
+ * challenge IA5STRING
+ * }
+ *
+ * SignedPublicKeyAndChallenge ::= SEQUENCE {
+ * publicKeyAndChallenge PublicKeyAndChallenge,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signature BIT STRING
+ * }
+ * </pre>
+ */
+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");
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/EncryptionException.java b/pkix/src/main/java/org/spongycastle/openssl/EncryptionException.java
new file mode 100644
index 00000000..64ef73eb
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/EncryptionException.java
@@ -0,0 +1,23 @@
+package org.spongycastle.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;
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/openssl/MiscPEMGenerator.java b/pkix/src/main/java/org/spongycastle/openssl/MiscPEMGenerator.java
new file mode 100644
index 00000000..995bf7b5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/MiscPEMGenerator.java
@@ -0,0 +1,209 @@
+package org.spongycastle.openssl;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.x509.DSAParameter;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.cert.X509AttributeCertificateHolder;
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.pkcs.PKCS10CertificationRequest;
+import org.spongycastle.util.Strings;
+import org.spongycastle.util.io.pem.PemGenerationException;
+import org.spongycastle.util.io.pem.PemHeader;
+import org.spongycastle.util.io.pem.PemObject;
+import org.spongycastle.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 ASN1Integer(0));
+ v.add(new ASN1Integer(p.getP()));
+ v.add(new ASN1Integer(p.getQ()));
+ v.add(new ASN1Integer(p.getG()));
+
+ BigInteger x = ASN1Integer.getInstance(info.parsePrivateKey()).getValue();
+ BigInteger y = p.getG().modPow(x, p.getP());
+
+ v.add(new ASN1Integer(y));
+ v.add(new ASN1Integer(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.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PEMDecryptor.java b/pkix/src/main/java/org/spongycastle/openssl/PEMDecryptor.java
new file mode 100644
index 00000000..3bd54df6
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PEMDecryptor.java
@@ -0,0 +1,7 @@
+package org.spongycastle.openssl;
+
+public interface PEMDecryptor
+{
+ byte[] decrypt(byte[] keyBytes, byte[] iv)
+ throws PEMException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PEMDecryptorProvider.java b/pkix/src/main/java/org/spongycastle/openssl/PEMDecryptorProvider.java
new file mode 100644
index 00000000..0d0b1e5c
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PEMDecryptorProvider.java
@@ -0,0 +1,9 @@
+package org.spongycastle.openssl;
+
+import org.spongycastle.operator.OperatorCreationException;
+
+public interface PEMDecryptorProvider
+{
+ PEMDecryptor get(String dekAlgName)
+ throws OperatorCreationException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PEMEncryptedKeyPair.java b/pkix/src/main/java/org/spongycastle/openssl/PEMEncryptedKeyPair.java
new file mode 100644
index 00000000..4a04de14
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PEMEncryptedKeyPair.java
@@ -0,0 +1,44 @@
+package org.spongycastle.openssl;
+
+import java.io.IOException;
+
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PEMEncryptor.java b/pkix/src/main/java/org/spongycastle/openssl/PEMEncryptor.java
new file mode 100644
index 00000000..63b42b2d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PEMEncryptor.java
@@ -0,0 +1,11 @@
+package org.spongycastle.openssl;
+
+public interface PEMEncryptor
+{
+ String getAlgorithm();
+
+ byte[] getIV();
+
+ byte[] encrypt(byte[] encoding)
+ throws PEMException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PEMException.java b/pkix/src/main/java/org/spongycastle/openssl/PEMException.java
new file mode 100644
index 00000000..5df7b5f5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PEMException.java
@@ -0,0 +1,34 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PEMKeyPair.java b/pkix/src/main/java/org/spongycastle/openssl/PEMKeyPair.java
new file mode 100644
index 00000000..ad010634
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PEMKeyPair.java
@@ -0,0 +1,26 @@
+package org.spongycastle.openssl;
+
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PEMKeyPairParser.java b/pkix/src/main/java/org/spongycastle/openssl/PEMKeyPairParser.java
new file mode 100644
index 00000000..32583fd9
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PEMKeyPairParser.java
@@ -0,0 +1,9 @@
+package org.spongycastle.openssl;
+
+import java.io.IOException;
+
+interface PEMKeyPairParser
+{
+ PEMKeyPair parse(byte[] encoding)
+ throws IOException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PEMParser.java b/pkix/src/main/java/org/spongycastle/openssl/PEMParser.java
new file mode 100644
index 00000000..bafe2126
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PEMParser.java
@@ -0,0 +1,510 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.pkcs.EncryptedPrivateKeyInfo;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.pkcs.RSAPublicKey;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.DSAParameter;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X9ECParameters;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.cert.X509AttributeCertificateHolder;
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.pkcs.PKCS10CertificationRequest;
+import org.spongycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
+import org.spongycastle.util.encoders.Hex;
+import org.spongycastle.util.io.pem.PemHeader;
+import org.spongycastle.util.io.pem.PemObject;
+import org.spongycastle.util.io.pem.PemObjectParser;
+import org.spongycastle.util.io.pem.PemReader;
+
+/**
+ * Class for parsing OpenSSL PEM encoded streams containing
+ * X509 certificates, PKCS8 encoded keys and PKCS7 objects.
+ * <p>
+ * 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.
+ * </p>
+ */
+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("TRUSTED 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.spongycastle.asn1.sec.ECPrivateKey pKey = org.spongycastle.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.spongycastle.asn1.pkcs.RSAPrivateKey keyStruct = org.spongycastle.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);
+ }
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PEMUtilities.java b/pkix/src/main/java/org/spongycastle/openssl/PEMUtilities.java
new file mode 100644
index 00000000..e8fec527
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PEMUtilities.java
@@ -0,0 +1,64 @@
+package org.spongycastle.openssl;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.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(ASN1ObjectIdentifier algOid)
+ {
+ return PKCS5_SCHEME_1.contains(algOid);
+ }
+
+ public static boolean isPKCS5Scheme2(ASN1ObjectIdentifier algOid)
+ {
+ return PKCS5_SCHEME_2.contains(algOid);
+ }
+
+ public static boolean isPKCS12(ASN1ObjectIdentifier algOid)
+ {
+ return algOid.getId().startsWith(PKCSObjectIdentifiers.pkcs_12PbeIds.getId());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PEMWriter.java b/pkix/src/main/java/org/spongycastle/openssl/PEMWriter.java
new file mode 100644
index 00000000..379c014d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PEMWriter.java
@@ -0,0 +1,69 @@
+package org.spongycastle.openssl;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.spongycastle.openssl.jcajce.JcaMiscPEMGenerator;
+import org.spongycastle.util.io.pem.PemGenerationException;
+import org.spongycastle.util.io.pem.PemObjectGenerator;
+import org.spongycastle.util.io.pem.PemWriter;
+
+/**
+ * General purpose writer for OpenSSL PEM objects.
+ * @deprecated use JcaPEMWriter
+ */
+public class PEMWriter
+ extends PemWriter
+{
+ /**
+ * Base constructor.
+ *
+ * @param out output stream to use.
+ */
+ public PEMWriter(Writer out)
+ {
+ super(out);
+ }
+
+ /**
+ * @throws IOException
+ */
+ public void writeObject(
+ Object obj)
+ throws IOException
+ {
+ writeObject(obj, null);
+ }
+
+ /**
+ * @param obj
+ * @param encryptor
+ * @throws IOException
+ */
+ 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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PKCS8Generator.java b/pkix/src/main/java/org/spongycastle/openssl/PKCS8Generator.java
new file mode 100644
index 00000000..83130d36
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PKCS8Generator.java
@@ -0,0 +1,87 @@
+package org.spongycastle.openssl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.EncryptedPrivateKeyInfo;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.util.io.pem.PemGenerationException;
+import org.spongycastle.util.io.pem.PemObject;
+import org.spongycastle.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;
+
+ /**
+ * Base constructor.
+ */
+ public PKCS8Generator(PrivateKeyInfo key, OutputEncryptor outputEncryptor)
+ {
+ this.key = key;
+ this.outputEncryptor = outputEncryptor;
+ }
+
+ public PemObject generate()
+ throws PemGenerationException
+ {
+ 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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PasswordException.java b/pkix/src/main/java/org/spongycastle/openssl/PasswordException.java
new file mode 100644
index 00000000..68de3213
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PasswordException.java
@@ -0,0 +1,10 @@
+package org.spongycastle.openssl;
+
+public class PasswordException
+ extends PEMException
+{
+ public PasswordException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/PasswordFinder.java b/pkix/src/main/java/org/spongycastle/openssl/PasswordFinder.java
new file mode 100644
index 00000000..eb981fd5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/PasswordFinder.java
@@ -0,0 +1,9 @@
+package org.spongycastle.openssl;
+
+/**
+ * call back to allow a password to be fetched when one is requested.
+ */
+public interface PasswordFinder
+{
+ public char[] getPassword();
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaMiscPEMGenerator.java b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaMiscPEMGenerator.java
new file mode 100644
index 00000000..88f2a32e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaMiscPEMGenerator.java
@@ -0,0 +1,98 @@
+package org.spongycastle.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.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.jcajce.JcaX509AttributeCertificateHolder;
+import org.spongycastle.cert.jcajce.JcaX509CRLHolder;
+import org.spongycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.spongycastle.jce.PKCS10CertificationRequest;
+import org.spongycastle.openssl.MiscPEMGenerator;
+import org.spongycastle.openssl.PEMEncryptor;
+import org.spongycastle.x509.X509AttributeCertificate;
+import org.spongycastle.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.spongycastle.pkcs.PKCS10CertificationRequest(((PKCS10CertificationRequest)o).getEncoded());
+ }
+
+ return o;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaPEMKeyConverter.java b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaPEMKeyConverter.java
new file mode 100644
index 00000000..1b15639a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaPEMKeyConverter.java
@@ -0,0 +1,115 @@
+package org.spongycastle.openssl.jcajce;
+
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.openssl.PEMException;
+import org.spongycastle.openssl.PEMKeyPair;
+
+public class JcaPEMKeyConverter
+{
+ private JcaJceHelper helper = new DefaultJcaJceHelper();
+
+ private static final Map algorithms = new HashMap();
+
+ static
+ {
+ algorithms.put(X9ObjectIdentifiers.id_ecPublicKey, "ECDSA");
+ algorithms.put(PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ algorithms.put(X9ObjectIdentifiers.id_dsa, "DSA");
+ }
+
+ 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
+ {
+ KeyFactory keyFactory = getKeyFactory(keyPair.getPrivateKeyInfo().getPrivateKeyAlgorithm());
+
+ 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
+ {
+ KeyFactory keyFactory = getKeyFactory(publicKeyInfo.getAlgorithm());
+
+ 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
+ {
+ KeyFactory keyFactory = getKeyFactory(privateKeyInfo.getPrivateKeyAlgorithm());
+
+ return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyInfo.getEncoded()));
+ }
+ catch (Exception e)
+ {
+ throw new PEMException("unable to convert key pair: " + e.getMessage(), e);
+ }
+ }
+
+ private KeyFactory getKeyFactory(AlgorithmIdentifier algId)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ ASN1ObjectIdentifier algorithm = algId.getAlgorithm();
+
+ String algName = (String)algorithms.get(algorithm);
+
+ if (algName == null)
+ {
+ algName = algorithm.getId();
+ }
+
+ return helper.createKeyFactory(algName);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaPEMWriter.java b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaPEMWriter.java
new file mode 100644
index 00000000..0224b89e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaPEMWriter.java
@@ -0,0 +1,68 @@
+package org.spongycastle.openssl.jcajce;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.spongycastle.openssl.PEMEncryptor;
+import org.spongycastle.util.io.pem.PemGenerationException;
+import org.spongycastle.util.io.pem.PemObjectGenerator;
+import org.spongycastle.util.io.pem.PemWriter;
+
+/**
+ * General purpose writer for OpenSSL PEM objects based on JCA/JCE classes.
+ */
+public class JcaPEMWriter
+ extends PemWriter
+{
+ /**
+ * Base constructor.
+ *
+ * @param out output stream to use.
+ */
+ public JcaPEMWriter(Writer out)
+ {
+ super(out);
+ }
+
+ /**
+ * @throws java.io.IOException
+ */
+ public void writeObject(
+ Object obj)
+ throws IOException
+ {
+ writeObject(obj, null);
+ }
+
+ /**
+ * @param obj
+ * @param encryptor
+ * @throws java.io.IOException
+ */
+ 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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaPKCS8Generator.java b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaPKCS8Generator.java
new file mode 100644
index 00000000..9c4e4f46
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcaPKCS8Generator.java
@@ -0,0 +1,18 @@
+package org.spongycastle.openssl.jcajce;
+
+import java.security.PrivateKey;
+
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.openssl.PKCS8Generator;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.util.io.pem.PemGenerationException;
+
+public class JcaPKCS8Generator
+ extends PKCS8Generator
+{
+ public JcaPKCS8Generator(PrivateKey key, OutputEncryptor encryptor)
+ throws PemGenerationException
+ {
+ super(PrivateKeyInfo.getInstance(key.getEncoded()), encryptor);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java
new file mode 100644
index 00000000..5050f4b2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java
@@ -0,0 +1,141 @@
+package org.spongycastle.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.spongycastle.asn1.pkcs.EncryptionScheme;
+import org.spongycastle.asn1.pkcs.KeyDerivationFunc;
+import org.spongycastle.asn1.pkcs.PBEParameter;
+import org.spongycastle.asn1.pkcs.PBES2Parameters;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.openssl.PEMException;
+import org.spongycastle.operator.InputDecryptor;
+import org.spongycastle.operator.InputDecryptorProvider;
+import org.spongycastle.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);
+ }
+ };
+ };
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java
new file mode 100644
index 00000000..8404661f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java
@@ -0,0 +1,221 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.KeyDerivationFunc;
+import org.spongycastle.asn1.pkcs.PBES2Parameters;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.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);
+ }
+ };
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcePEMDecryptorProviderBuilder.java b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcePEMDecryptorProviderBuilder.java
new file mode 100644
index 00000000..b54d7fd3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcePEMDecryptorProviderBuilder.java
@@ -0,0 +1,54 @@
+package org.spongycastle.openssl.jcajce;
+
+import java.security.Provider;
+
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.openssl.PEMDecryptor;
+import org.spongycastle.openssl.PEMDecryptorProvider;
+import org.spongycastle.openssl.PEMException;
+import org.spongycastle.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);
+ }
+ };
+ }
+ };
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcePEMEncryptorBuilder.java b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcePEMEncryptorBuilder.java
new file mode 100644
index 00000000..3360f8a8
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/jcajce/JcePEMEncryptorBuilder.java
@@ -0,0 +1,78 @@
+package org.spongycastle.openssl.jcajce;
+
+import java.security.Provider;
+import java.security.SecureRandom;
+
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.openssl.PEMEncryptor;
+import org.spongycastle.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);
+ }
+ };
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/openssl/jcajce/PEMUtilities.java b/pkix/src/main/java/org/spongycastle/openssl/jcajce/PEMUtilities.java
new file mode 100644
index 00000000..6bfa2a57
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/openssl/jcajce/PEMUtilities.java
@@ -0,0 +1,257 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.crypto.PBEParametersGenerator;
+import org.spongycastle.crypto.generators.OpenSSLPBEParametersGenerator;
+import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.openssl.EncryptionException;
+import org.spongycastle.openssl.PEMException;
+import org.spongycastle.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(ASN1ObjectIdentifier algOid)
+ {
+ return PKCS5_SCHEME_1.contains(algOid);
+ }
+
+ static boolean isPKCS5Scheme2(ASN1ObjectIdentifier algOid)
+ {
+ return PKCS5_SCHEME_2.contains(algOid);
+ }
+
+ public static boolean isPKCS12(ASN1ObjectIdentifier 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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/AsymmetricKeyUnwrapper.java b/pkix/src/main/java/org/spongycastle/operator/AsymmetricKeyUnwrapper.java
new file mode 100644
index 00000000..2ed2f145
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/AsymmetricKeyUnwrapper.java
@@ -0,0 +1,19 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public abstract class AsymmetricKeyUnwrapper
+ implements KeyUnwrapper
+{
+ private AlgorithmIdentifier algorithmId;
+
+ protected AsymmetricKeyUnwrapper(AlgorithmIdentifier algorithmId)
+ {
+ this.algorithmId = algorithmId;
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithmId;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/AsymmetricKeyWrapper.java b/pkix/src/main/java/org/spongycastle/operator/AsymmetricKeyWrapper.java
new file mode 100644
index 00000000..3de80226
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/AsymmetricKeyWrapper.java
@@ -0,0 +1,19 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public abstract class AsymmetricKeyWrapper
+ implements KeyWrapper
+{
+ private AlgorithmIdentifier algorithmId;
+
+ protected AsymmetricKeyWrapper(AlgorithmIdentifier algorithmId)
+ {
+ this.algorithmId = algorithmId;
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithmId;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/BufferingContentSigner.java b/pkix/src/main/java/org/spongycastle/operator/BufferingContentSigner.java
new file mode 100644
index 00000000..e96a906c
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/BufferingContentSigner.java
@@ -0,0 +1,70 @@
+package org.spongycastle.operator;
+
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.util.io.BufferingOutputStream;
+
+/**
+ * A class that explicitly buffers the data to be signed, sending it in one
+ * block when ready for signing.
+ */
+public class BufferingContentSigner
+ implements ContentSigner
+{
+ private final ContentSigner contentSigner;
+ private final OutputStream output;
+
+ /**
+ * Base constructor.
+ *
+ * @param contentSigner the content signer to be wrapped.
+ */
+ public BufferingContentSigner(ContentSigner contentSigner)
+ {
+ this.contentSigner = contentSigner;
+ this.output = new BufferingOutputStream(contentSigner.getOutputStream());
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param contentSigner the content signer to be wrapped.
+ * @param bufferSize the size of the internal buffer to use.
+ */
+ public BufferingContentSigner(ContentSigner contentSigner, int bufferSize)
+ {
+ this.contentSigner = contentSigner;
+ this.output = new BufferingOutputStream(contentSigner.getOutputStream(), bufferSize);
+ }
+
+ /**
+ * Return the algorithm identifier supported by this signer.
+ *
+ * @return algorithm identifier for the signature generated.
+ */
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return contentSigner.getAlgorithmIdentifier();
+ }
+
+ /**
+ * Return the buffering stream.
+ *
+ * @return the output stream used to accumulate the data.
+ */
+ public OutputStream getOutputStream()
+ {
+ return output;
+ }
+
+ /**
+ * Generate signature from internally buffered data.
+ *
+ * @return the signature calculated from the bytes written to the buffering stream.
+ */
+ public byte[] getSignature()
+ {
+ return contentSigner.getSignature();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/ContentSigner.java b/pkix/src/main/java/org/spongycastle/operator/ContentSigner.java
new file mode 100644
index 00000000..fcdeefc4
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/ContentSigner.java
@@ -0,0 +1,27 @@
+package org.spongycastle.operator;
+
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface ContentSigner
+{
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ /**
+ * Returns a stream that will accept data for the purpose of calculating
+ * a signature. Use org.spongycastle.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();
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/ContentVerifier.java b/pkix/src/main/java/org/spongycastle/operator/ContentVerifier.java
new file mode 100644
index 00000000..a139ebb2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/ContentVerifier.java
@@ -0,0 +1,31 @@
+package org.spongycastle.operator;
+
+import java.io.OutputStream;
+
+import org.spongycastle.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.spongycastle.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);
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/ContentVerifierProvider.java b/pkix/src/main/java/org/spongycastle/operator/ContentVerifierProvider.java
new file mode 100644
index 00000000..9d91304a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/ContentVerifierProvider.java
@@ -0,0 +1,34 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.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;
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/spongycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
new file mode 100644
index 00000000..42d6665e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
@@ -0,0 +1,97 @@
+package org.spongycastle.operator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RSASSAPSSparams;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/DefaultSecretKeySizeProvider.java b/pkix/src/main/java/org/spongycastle/operator/DefaultSecretKeySizeProvider.java
new file mode 100644
index 00000000..d830e5cc
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/DefaultSecretKeySizeProvider.java
@@ -0,0 +1,69 @@
+package org.spongycastle.operator;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.util.Integers;
+
+public class DefaultSecretKeySizeProvider
+ implements SecretKeySizeProvider
+{
+ public static final SecretKeySizeProvider INSTANCE = new DefaultSecretKeySizeProvider();
+
+ 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, 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));
+
+ keySizes.put(CryptoProObjectIdentifiers.gostR28147_gcfb, Integers.valueOf(256));
+
+ KEY_SIZES = Collections.unmodifiableMap(keySizes);
+ }
+
+ public int getKeySize(AlgorithmIdentifier algorithmIdentifier)
+ {
+ int keySize = getKeySize(algorithmIdentifier.getAlgorithm());
+
+ // just need the OID
+ if (keySize > 0)
+ {
+ return keySize;
+ }
+
+ // TODO: support OID/Parameter key sizes (e.g. RC2).
+
+ return -1;
+ }
+
+ public int getKeySize(ASN1ObjectIdentifier algorithm)
+ {
+ Integer keySize = (Integer)KEY_SIZES.get(algorithm);
+
+ if (keySize != null)
+ {
+ return keySize.intValue();
+ }
+
+ return -1;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/spongycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
new file mode 100644
index 00000000..58608c8b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
@@ -0,0 +1,224 @@
+package org.spongycastle.operator;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.bsi.BSIObjectIdentifiers;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.eac.EACObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RSASSAPSSparams;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.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);
+ algorithms.put("SHA1WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA1);
+ algorithms.put("SHA224WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA224);
+ algorithms.put("SHA256WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA256);
+ algorithms.put("SHA384WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA384);
+ algorithms.put("SHA512WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_SHA512);
+ algorithms.put("RIPEMD160WITHPLAIN-ECDSA", BSIObjectIdentifiers.ecdsa_plain_RIPEMD160);
+ algorithms.put("SHA1WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_1);
+ algorithms.put("SHA224WITHPCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_224);
+ algorithms.put("SHA256WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_256);
+ algorithms.put("SHA384WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_384);
+ algorithms.put("SHA512WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_512);
+ //
+ // 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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/DigestAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/spongycastle/operator/DigestAlgorithmIdentifierFinder.java
new file mode 100644
index 00000000..1254c38e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/DigestAlgorithmIdentifierFinder.java
@@ -0,0 +1,24 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.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);
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/DigestCalculator.java b/pkix/src/main/java/org/spongycastle/operator/DigestCalculator.java
new file mode 100644
index 00000000..0bb4712f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/DigestCalculator.java
@@ -0,0 +1,36 @@
+package org.spongycastle.operator;
+
+import java.io.OutputStream;
+
+import org.spongycastle.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.spongycastle.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();
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/DigestCalculatorProvider.java b/pkix/src/main/java/org/spongycastle/operator/DigestCalculatorProvider.java
new file mode 100644
index 00000000..55a7c143
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/DigestCalculatorProvider.java
@@ -0,0 +1,9 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface DigestCalculatorProvider
+{
+ DigestCalculator get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ throws OperatorCreationException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/GenericKey.java b/pkix/src/main/java/org/spongycastle/operator/GenericKey.java
new file mode 100644
index 00000000..5446ce7b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/GenericKey.java
@@ -0,0 +1,41 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/InputDecryptor.java b/pkix/src/main/java/org/spongycastle/operator/InputDecryptor.java
new file mode 100644
index 00000000..c55b3db0
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/InputDecryptor.java
@@ -0,0 +1,29 @@
+package org.spongycastle.operator;
+
+import java.io.InputStream;
+
+import org.spongycastle.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);
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/InputDecryptorProvider.java b/pkix/src/main/java/org/spongycastle/operator/InputDecryptorProvider.java
new file mode 100644
index 00000000..4ef7e9c0
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/InputDecryptorProvider.java
@@ -0,0 +1,9 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface InputDecryptorProvider
+{
+ public InputDecryptor get(AlgorithmIdentifier algorithm)
+ throws OperatorCreationException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/InputExpander.java b/pkix/src/main/java/org/spongycastle/operator/InputExpander.java
new file mode 100644
index 00000000..870e4807
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/InputExpander.java
@@ -0,0 +1,29 @@
+package org.spongycastle.operator;
+
+import java.io.InputStream;
+
+import org.spongycastle.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);
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/InputExpanderProvider.java b/pkix/src/main/java/org/spongycastle/operator/InputExpanderProvider.java
new file mode 100644
index 00000000..d38b813a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/InputExpanderProvider.java
@@ -0,0 +1,8 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface InputExpanderProvider
+{
+ InputExpander get(AlgorithmIdentifier algorithm);
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/KeyUnwrapper.java b/pkix/src/main/java/org/spongycastle/operator/KeyUnwrapper.java
new file mode 100644
index 00000000..8e216230
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/KeyUnwrapper.java
@@ -0,0 +1,11 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface KeyUnwrapper
+{
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ GenericKey generateUnwrappedKey(AlgorithmIdentifier encryptionKeyAlgorithm, byte[] encryptedKey)
+ throws OperatorException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/KeyWrapper.java b/pkix/src/main/java/org/spongycastle/operator/KeyWrapper.java
new file mode 100644
index 00000000..4b7986df
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/KeyWrapper.java
@@ -0,0 +1,11 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface KeyWrapper
+{
+ AlgorithmIdentifier getAlgorithmIdentifier();
+
+ byte[] generateWrappedKey(GenericKey encryptionKey)
+ throws OperatorException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/MacCalculator.java b/pkix/src/main/java/org/spongycastle/operator/MacCalculator.java
new file mode 100644
index 00000000..df59ed65
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/MacCalculator.java
@@ -0,0 +1,34 @@
+package org.spongycastle.operator;
+
+import java.io.OutputStream;
+
+import org.spongycastle.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.spongycastle.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();
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/MacCalculatorProvider.java b/pkix/src/main/java/org/spongycastle/operator/MacCalculatorProvider.java
new file mode 100644
index 00000000..a30773f2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/MacCalculatorProvider.java
@@ -0,0 +1,8 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface MacCalculatorProvider
+{
+ public MacCalculator get(AlgorithmIdentifier algorithm);
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/OperatorCreationException.java b/pkix/src/main/java/org/spongycastle/operator/OperatorCreationException.java
new file mode 100644
index 00000000..4e7cadac
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/OperatorCreationException.java
@@ -0,0 +1,15 @@
+package org.spongycastle.operator;
+
+public class OperatorCreationException
+ extends OperatorException
+{
+ public OperatorCreationException(String msg, Throwable cause)
+ {
+ super(msg, cause);
+ }
+
+ public OperatorCreationException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/OperatorException.java b/pkix/src/main/java/org/spongycastle/operator/OperatorException.java
new file mode 100644
index 00000000..32ce9e41
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/OperatorException.java
@@ -0,0 +1,24 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/OperatorStreamException.java b/pkix/src/main/java/org/spongycastle/operator/OperatorStreamException.java
new file mode 100644
index 00000000..960d292f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/OperatorStreamException.java
@@ -0,0 +1,21 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/OutputCompressor.java b/pkix/src/main/java/org/spongycastle/operator/OutputCompressor.java
new file mode 100644
index 00000000..0e10df9a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/OutputCompressor.java
@@ -0,0 +1,29 @@
+package org.spongycastle.operator;
+
+import java.io.OutputStream;
+
+import org.spongycastle.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);
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/OutputEncryptor.java b/pkix/src/main/java/org/spongycastle/operator/OutputEncryptor.java
new file mode 100644
index 00000000..595e3b75
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/OutputEncryptor.java
@@ -0,0 +1,36 @@
+package org.spongycastle.operator;
+
+import java.io.OutputStream;
+
+import org.spongycastle.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();
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/RawContentVerifier.java b/pkix/src/main/java/org/spongycastle/operator/RawContentVerifier.java
new file mode 100644
index 00000000..56bfb47f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/RawContentVerifier.java
@@ -0,0 +1,17 @@
+package org.spongycastle.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);
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/RuntimeOperatorException.java b/pkix/src/main/java/org/spongycastle/operator/RuntimeOperatorException.java
new file mode 100644
index 00000000..56cab04a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/RuntimeOperatorException.java
@@ -0,0 +1,24 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/SecretKeySizeProvider.java b/pkix/src/main/java/org/spongycastle/operator/SecretKeySizeProvider.java
new file mode 100644
index 00000000..cb2d6561
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/SecretKeySizeProvider.java
@@ -0,0 +1,17 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface SecretKeySizeProvider
+{
+ int getKeySize(AlgorithmIdentifier algorithmIdentifier);
+
+ /**
+ * Return the key size implied by the OID, if one exists.
+ *
+ * @param algorithm the OID of the algorithm of interest.
+ * @return -1 if there is no fixed key size associated with the OID, or more information is required.
+ */
+ int getKeySize(ASN1ObjectIdentifier algorithm);
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/SignatureAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/spongycastle/operator/SignatureAlgorithmIdentifierFinder.java
new file mode 100644
index 00000000..5c997bda
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/SignatureAlgorithmIdentifierFinder.java
@@ -0,0 +1,15 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.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);
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/SymmetricKeyUnwrapper.java b/pkix/src/main/java/org/spongycastle/operator/SymmetricKeyUnwrapper.java
new file mode 100644
index 00000000..705a7671
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/SymmetricKeyUnwrapper.java
@@ -0,0 +1,19 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public abstract class SymmetricKeyUnwrapper
+ implements KeyUnwrapper
+{
+ private AlgorithmIdentifier algorithmId;
+
+ protected SymmetricKeyUnwrapper(AlgorithmIdentifier algorithmId)
+ {
+ this.algorithmId = algorithmId;
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithmId;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/SymmetricKeyWrapper.java b/pkix/src/main/java/org/spongycastle/operator/SymmetricKeyWrapper.java
new file mode 100644
index 00000000..56ac7ef1
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/SymmetricKeyWrapper.java
@@ -0,0 +1,19 @@
+package org.spongycastle.operator;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public abstract class SymmetricKeyWrapper
+ implements KeyWrapper
+{
+ private AlgorithmIdentifier algorithmId;
+
+ protected SymmetricKeyWrapper(AlgorithmIdentifier algorithmId)
+ {
+ this.algorithmId = algorithmId;
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return algorithmId;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/AESUtil.java b/pkix/src/main/java/org/spongycastle/operator/bc/AESUtil.java
new file mode 100644
index 00000000..7abd31be
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/AESUtil.java
@@ -0,0 +1,34 @@
+package org.spongycastle.operator.bc;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.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
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java
new file mode 100644
index 00000000..f9b8c09b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcAESSymmetricKeyUnwrapper.java
@@ -0,0 +1,13 @@
+package org.spongycastle.operator.bc;
+
+import org.spongycastle.crypto.engines.AESWrapEngine;
+import org.spongycastle.crypto.params.KeyParameter;
+
+public class BcAESSymmetricKeyUnwrapper
+ extends BcSymmetricKeyUnwrapper
+{
+ public BcAESSymmetricKeyUnwrapper(KeyParameter wrappingKey)
+ {
+ super(AESUtil.determineKeyEncAlg(wrappingKey), new AESWrapEngine(), wrappingKey);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcAESSymmetricKeyWrapper.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcAESSymmetricKeyWrapper.java
new file mode 100644
index 00000000..62dc062f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcAESSymmetricKeyWrapper.java
@@ -0,0 +1,13 @@
+package org.spongycastle.operator.bc;
+
+import org.spongycastle.crypto.engines.AESWrapEngine;
+import org.spongycastle.crypto.params.KeyParameter;
+
+public class BcAESSymmetricKeyWrapper
+ extends BcSymmetricKeyWrapper
+{
+ public BcAESSymmetricKeyWrapper(KeyParameter wrappingKey)
+ {
+ super(AESUtil.determineKeyEncAlg(wrappingKey), new AESWrapEngine(), wrappingKey);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcAsymmetricKeyUnwrapper.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcAsymmetricKeyUnwrapper.java
new file mode 100644
index 00000000..8fed9deb
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcAsymmetricKeyUnwrapper.java
@@ -0,0 +1,51 @@
+package org.spongycastle.operator.bc;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.AsymmetricBlockCipher;
+import org.spongycastle.crypto.InvalidCipherTextException;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.operator.AsymmetricKeyUnwrapper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.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);
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcAsymmetricKeyWrapper.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcAsymmetricKeyWrapper.java
new file mode 100644
index 00000000..8b5bb3e8
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcAsymmetricKeyWrapper.java
@@ -0,0 +1,60 @@
+package org.spongycastle.operator.bc;
+
+import java.security.SecureRandom;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.AsymmetricBlockCipher;
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.InvalidCipherTextException;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.crypto.params.ParametersWithRandom;
+import org.spongycastle.operator.AsymmetricKeyWrapper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.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);
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcContentSignerBuilder.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcContentSignerBuilder.java
new file mode 100644
index 00000000..7160adff
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcContentSignerBuilder.java
@@ -0,0 +1,82 @@
+package org.spongycastle.operator.bc;
+
+import java.io.OutputStream;
+import java.security.SecureRandom;
+import java.util.Map;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.CryptoException;
+import org.spongycastle.crypto.Signer;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.crypto.params.ParametersWithRandom;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.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;
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcContentVerifierProviderBuilder.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcContentVerifierProviderBuilder.java
new file mode 100644
index 00000000..3b975e4f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcContentVerifierProviderBuilder.java
@@ -0,0 +1,144 @@
+package org.spongycastle.operator.bc;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.crypto.Signer;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.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);
+ }
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcDSAContentSignerBuilder.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcDSAContentSignerBuilder.java
new file mode 100644
index 00000000..db7b608d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcDSAContentSignerBuilder.java
@@ -0,0 +1,25 @@
+package org.spongycastle.operator.bc;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.Signer;
+import org.spongycastle.crypto.signers.DSADigestSigner;
+import org.spongycastle.crypto.signers.DSASigner;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java
new file mode 100644
index 00000000..aaf25f4d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcDSAContentVerifierProviderBuilder.java
@@ -0,0 +1,40 @@
+package org.spongycastle.operator.bc;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.Signer;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.crypto.signers.DSADigestSigner;
+import org.spongycastle.crypto.signers.DSASigner;
+import org.spongycastle.crypto.util.PublicKeyFactory;
+import org.spongycastle.operator.DigestAlgorithmIdentifierFinder;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcDefaultDigestProvider.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcDefaultDigestProvider.java
new file mode 100644
index 00000000..dce50a9e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcDefaultDigestProvider.java
@@ -0,0 +1,144 @@
+package org.spongycastle.operator.bc;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.ExtendedDigest;
+import org.spongycastle.crypto.digests.GOST3411Digest;
+import org.spongycastle.crypto.digests.MD2Digest;
+import org.spongycastle.crypto.digests.MD4Digest;
+import org.spongycastle.crypto.digests.MD5Digest;
+import org.spongycastle.crypto.digests.RIPEMD128Digest;
+import org.spongycastle.crypto.digests.RIPEMD160Digest;
+import org.spongycastle.crypto.digests.RIPEMD256Digest;
+import org.spongycastle.crypto.digests.SHA1Digest;
+import org.spongycastle.crypto.digests.SHA224Digest;
+import org.spongycastle.crypto.digests.SHA256Digest;
+import org.spongycastle.crypto.digests.SHA384Digest;
+import org.spongycastle.crypto.digests.SHA512Digest;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcDigestCalculatorProvider.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcDigestCalculatorProvider.java
new file mode 100644
index 00000000..8e0a12f6
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcDigestCalculatorProvider.java
@@ -0,0 +1,82 @@
+package org.spongycastle.operator.bc;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.ExtendedDigest;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.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;
+ }
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcDigestProvider.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcDigestProvider.java
new file mode 100644
index 00000000..6eb930ee
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcDigestProvider.java
@@ -0,0 +1,11 @@
+package org.spongycastle.operator.bc;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.ExtendedDigest;
+import org.spongycastle.operator.OperatorCreationException;
+
+public interface BcDigestProvider
+{
+ ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ throws OperatorCreationException;
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java
new file mode 100644
index 00000000..99762353
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcRSAAsymmetricKeyUnwrapper.java
@@ -0,0 +1,22 @@
+package org.spongycastle.operator.bc;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.AsymmetricBlockCipher;
+import org.spongycastle.crypto.encodings.PKCS1Encoding;
+import org.spongycastle.crypto.engines.RSAEngine;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java
new file mode 100644
index 00000000..c2153e6d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcRSAAsymmetricKeyWrapper.java
@@ -0,0 +1,32 @@
+package org.spongycastle.operator.bc;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.crypto.AsymmetricBlockCipher;
+import org.spongycastle.crypto.encodings.PKCS1Encoding;
+import org.spongycastle.crypto.engines.RSAEngine;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcRSAContentSignerBuilder.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcRSAContentSignerBuilder.java
new file mode 100644
index 00000000..d62543b0
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcRSAContentSignerBuilder.java
@@ -0,0 +1,24 @@
+package org.spongycastle.operator.bc;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.Signer;
+import org.spongycastle.crypto.signers.RSADigestSigner;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java
new file mode 100644
index 00000000..e1fd6736
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcRSAContentVerifierProviderBuilder.java
@@ -0,0 +1,39 @@
+package org.spongycastle.operator.bc;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.Signer;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.crypto.signers.RSADigestSigner;
+import org.spongycastle.crypto.util.PublicKeyFactory;
+import org.spongycastle.operator.DigestAlgorithmIdentifierFinder;
+import org.spongycastle.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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcSignerOutputStream.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcSignerOutputStream.java
new file mode 100644
index 00000000..f4cdf62b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcSignerOutputStream.java
@@ -0,0 +1,47 @@
+package org.spongycastle.operator.bc;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.crypto.CryptoException;
+import org.spongycastle.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);
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcSymmetricKeyUnwrapper.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcSymmetricKeyUnwrapper.java
new file mode 100644
index 00000000..da37cf1a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcSymmetricKeyUnwrapper.java
@@ -0,0 +1,49 @@
+package org.spongycastle.operator.bc;
+
+import java.security.SecureRandom;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.InvalidCipherTextException;
+import org.spongycastle.crypto.Wrapper;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OperatorException;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/BcSymmetricKeyWrapper.java b/pkix/src/main/java/org/spongycastle/operator/bc/BcSymmetricKeyWrapper.java
new file mode 100644
index 00000000..a35de7d7
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/BcSymmetricKeyWrapper.java
@@ -0,0 +1,51 @@
+package org.spongycastle.operator.bc;
+
+import java.security.SecureRandom;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.Wrapper;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.crypto.params.ParametersWithRandom;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OperatorException;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/CamelliaUtil.java b/pkix/src/main/java/org/spongycastle/operator/bc/CamelliaUtil.java
new file mode 100644
index 00000000..9b7c9836
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/CamelliaUtil.java
@@ -0,0 +1,36 @@
+package org.spongycastle.operator.bc;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.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
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/OperatorUtils.java b/pkix/src/main/java/org/spongycastle/operator/bc/OperatorUtils.java
new file mode 100644
index 00000000..a53c4692
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/OperatorUtils.java
@@ -0,0 +1,23 @@
+package org.spongycastle.operator.bc;
+
+import java.security.Key;
+
+import org.spongycastle.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");
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/bc/SEEDUtil.java b/pkix/src/main/java/org/spongycastle/operator/bc/SEEDUtil.java
new file mode 100644
index 00000000..4d977310
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/bc/SEEDUtil.java
@@ -0,0 +1,14 @@
+package org.spongycastle.operator.bc;
+
+import org.spongycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+class SEEDUtil
+{
+ static AlgorithmIdentifier determineKeyEncAlg()
+ {
+ // parameters absent
+ return new AlgorithmIdentifier(
+ KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java b/pkix/src/main/java/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
new file mode 100644
index 00000000..98e2b929
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
@@ -0,0 +1,73 @@
+package org.spongycastle.operator.jcajce;
+
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.MGF1ParameterSpec;
+
+import javax.crypto.spec.OAEPParameterSpec;
+import javax.crypto.spec.PSource;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RSAESOAEPparams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+
+public class JcaAlgorithmParametersConverter
+{
+ public JcaAlgorithmParametersConverter()
+ {
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algId, AlgorithmParameters parameters)
+ throws InvalidAlgorithmParameterException
+ {
+ try
+ {
+ ASN1Encodable params = ASN1Primitive.fromByteArray(parameters.getEncoded());
+
+ return new AlgorithmIdentifier(algId, params);
+ }
+ catch (IOException e)
+ {
+ throw new InvalidAlgorithmParameterException("unable to encode parameters object: " + e.getMessage());
+ }
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algorithm, AlgorithmParameterSpec algorithmSpec)
+ throws InvalidAlgorithmParameterException
+ {
+ if (algorithmSpec instanceof OAEPParameterSpec)
+ {
+ if (algorithmSpec.equals(OAEPParameterSpec.DEFAULT))
+ {
+ return new AlgorithmIdentifier(algorithm,
+ new RSAESOAEPparams(RSAESOAEPparams.DEFAULT_HASH_ALGORITHM, RSAESOAEPparams.DEFAULT_MASK_GEN_FUNCTION, RSAESOAEPparams.DEFAULT_P_SOURCE_ALGORITHM));
+ }
+ else
+ {
+ OAEPParameterSpec oaepSpec = (OAEPParameterSpec)algorithmSpec;
+ PSource pSource = oaepSpec.getPSource();
+
+ if (!oaepSpec.getMGFAlgorithm().equals(OAEPParameterSpec.DEFAULT.getMGFAlgorithm()))
+ {
+ throw new InvalidAlgorithmParameterException("only " + OAEPParameterSpec.DEFAULT.getMGFAlgorithm() + " mask generator supported.");
+ }
+
+ AlgorithmIdentifier hashAlgorithm = new DefaultDigestAlgorithmIdentifierFinder().find(oaepSpec.getDigestAlgorithm());
+ AlgorithmIdentifier mgf1HashAlgorithm = new DefaultDigestAlgorithmIdentifierFinder().find((((MGF1ParameterSpec)oaepSpec.getMGFParameters()).getDigestAlgorithm()));
+ return new AlgorithmIdentifier(algorithm,
+ new RSAESOAEPparams(hashAlgorithm, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, mgf1HashAlgorithm),
+ new AlgorithmIdentifier(PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(((PSource.PSpecified)pSource).getValue()))));
+ }
+ }
+
+ throw new InvalidAlgorithmParameterException("unknown parameter spec passed.");
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/jcajce/JcaContentSignerBuilder.java b/pkix/src/main/java/org/spongycastle/operator/jcajce/JcaContentSignerBuilder.java
new file mode 100644
index 00000000..f3a008dd
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/jcajce/JcaContentSignerBuilder.java
@@ -0,0 +1,160 @@
+package org.spongycastle.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.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.OperatorStreamException;
+import org.spongycastle.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();
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java b/pkix/src/main/java/org/spongycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
new file mode 100644
index 00000000..7b5690e4
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
@@ -0,0 +1,312 @@
+package org.spongycastle.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.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.OperatorStreamException;
+import org.spongycastle.operator.RawContentVerifier;
+import org.spongycastle.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);
+ }
+ }
+ };
+ }
+
+ public ContentVerifierProvider build(SubjectPublicKeyInfo publicKey)
+ throws OperatorCreationException
+ {
+ return this.build(helper.convertPublicKey(publicKey));
+ }
+
+ 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);
+ }
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java b/pkix/src/main/java/org/spongycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java
new file mode 100644
index 00000000..c734b866
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/jcajce/JcaDigestCalculatorProviderBuilder.java
@@ -0,0 +1,114 @@
+package org.spongycastle.operator.jcajce;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.Provider;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.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();
+ }
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java b/pkix/src/main/java/org/spongycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
new file mode 100644
index 00000000..0b5cbf60
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
@@ -0,0 +1,133 @@
+package org.spongycastle.operator.jcajce;
+
+import java.security.AlgorithmParameters;
+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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.AsymmetricKeyUnwrapper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.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.
+ * <p>
+ * For example:
+ * <pre>
+ * unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ * </pre>
+ * </p>
+ * @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);
+ AlgorithmParameters algParams = helper.createAlgorithmParameters(this.getAlgorithmIdentifier());
+
+ try
+ {
+ if (algParams != null)
+ {
+ keyCipher.init(Cipher.UNWRAP_MODE, privKey, algParams);
+ }
+ else
+ {
+ 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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/jcajce/JceAsymmetricKeyWrapper.java b/pkix/src/main/java/org/spongycastle/operator/jcajce/JceAsymmetricKeyWrapper.java
new file mode 100644
index 00000000..95eb3b9a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/jcajce/JceAsymmetricKeyWrapper.java
@@ -0,0 +1,157 @@
+package org.spongycastle.operator.jcajce;
+
+import java.security.AlgorithmParameters;
+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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.AsymmetricKeyWrapper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.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());
+ }
+
+ /**
+ * Create a wrapper, overriding the algorithm type that is stored in the public key.
+ *
+ * @param algorithmIdentifier identifier for encryption algorithm to be used.
+ * @param publicKey the public key to be used.
+ */
+ public JceAsymmetricKeyWrapper(AlgorithmIdentifier algorithmIdentifier, PublicKey publicKey)
+ {
+ super(algorithmIdentifier);
+
+ this.publicKey = publicKey;
+ }
+
+ 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.
+ * <p>
+ * For example:
+ * <pre>
+ * unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ * </pre>
+ * </p>
+ * @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);
+ AlgorithmParameters algParams = helper.createAlgorithmParameters(this.getAlgorithmIdentifier());
+
+ byte[] encryptedKeyBytes = null;
+
+ try
+ {
+ if (algParams != null)
+ {
+ keyEncryptionCipher.init(Cipher.WRAP_MODE, publicKey, algParams, random);
+ }
+ else
+ {
+ 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/jcajce/JceGenericKey.java b/pkix/src/main/java/org/spongycastle/operator/jcajce/JceGenericKey.java
new file mode 100644
index 00000000..a11a535e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/jcajce/JceGenericKey.java
@@ -0,0 +1,33 @@
+package org.spongycastle.operator.jcajce;
+
+import java.security.Key;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.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));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java b/pkix/src/main/java/org/spongycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java
new file mode 100644
index 00000000..dd9e7e0a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/jcajce/JceSymmetricKeyUnwrapper.java
@@ -0,0 +1,65 @@
+package org.spongycastle.operator.jcajce;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OperatorException;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/jcajce/JceSymmetricKeyWrapper.java b/pkix/src/main/java/org/spongycastle/operator/jcajce/JceSymmetricKeyWrapper.java
new file mode 100644
index 00000000..3689f6c2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/jcajce/JceSymmetricKeyWrapper.java
@@ -0,0 +1,154 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OperatorException;
+import org.spongycastle.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");
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/jcajce/OperatorHelper.java b/pkix/src/main/java/org/spongycastle/operator/jcajce/OperatorHelper.java
new file mode 100644
index 00000000..8f2776ae
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/jcajce/OperatorHelper.java
@@ -0,0 +1,433 @@
+package org.spongycastle.operator.jcajce;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+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.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PSSParameterSpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.bsi.BSIObjectIdentifiers;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.eac.EACObjectIdentifiers;
+import org.spongycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RSASSAPSSparams;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceUtils;
+import org.spongycastle.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(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1WITHPLAIN-ECDSA");
+ oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224WITHPLAIN-ECDSA");
+ oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256WITHPLAIN-ECDSA");
+ oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384WITHPLAIN-ECDSA");
+ oids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512WITHPLAIN-ECDSA");
+ oids.put(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160WITHPLAIN-ECDSA");
+ oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1WITHCVC-ECDSA");
+ oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224WITHCVC-ECDSA");
+ oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256WITHCVC-ECDSA");
+ oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384WITHCVC-ECDSA");
+ oids.put(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512WITHCVC-ECDSA");
+
+ 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, "RIPEMD128");
+ oids.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD160");
+ oids.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD256");
+
+ 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);
+ }
+ }
+
+ AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)
+ throws OperatorCreationException
+ {
+ AlgorithmParameters parameters;
+
+ if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
+ {
+ return null;
+ }
+
+ try
+ {
+ parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ return null; // There's a good chance there aren't any!
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
+ }
+
+ try
+ {
+ parameters.init(cipherAlgId.getParameters().toASN1Primitive().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("cannot initialise algorithm parameters: " + e.getMessage(), e);
+ }
+
+ return parameters;
+ }
+
+ MessageDigest createDigest(AlgorithmIdentifier digAlgId)
+ throws GeneralSecurityException
+ {
+ MessageDigest dig;
+
+ try
+ {
+ dig = helper.createDigest(JcaJceUtils.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);
+
+ JcaJceUtils.loadParameters(params, algorithm.getParameters());
+
+ 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 JcaJceUtils.getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAANDMGF1";
+ }
+ }
+
+ if (oids.containsKey(sigAlgId.getAlgorithm()))
+ {
+ return (String)oids.get(sigAlgId.getAlgorithm());
+ }
+
+ return sigAlgId.getAlgorithm().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);
+ }
+ }
+
+ public PublicKey convertPublicKey(SubjectPublicKeyInfo publicKeyInfo)
+ throws OperatorCreationException
+ {
+ try
+ {
+ KeyFactory keyFact = helper.createKeyFactory(publicKeyInfo.getAlgorithm().getAlgorithm().getId());
+
+ return keyFact.generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("cannot get encoded form of key: " + e.getMessage(), e);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot find factory provider: " + e.getMessage(), e);
+ }
+ catch (InvalidKeySpecException e)
+ {
+ throw new OperatorCreationException("cannot create key factory: " + 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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/operator/jcajce/OperatorUtils.java b/pkix/src/main/java/org/spongycastle/operator/jcajce/OperatorUtils.java
new file mode 100644
index 00000000..81cb4063
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/operator/jcajce/OperatorUtils.java
@@ -0,0 +1,25 @@
+package org.spongycastle.operator.jcajce;
+
+import java.security.Key;
+
+import javax.crypto.spec.SecretKeySpec;
+
+import org.spongycastle.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");
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/MacDataGenerator.java b/pkix/src/main/java/org/spongycastle/pkcs/MacDataGenerator.java
new file mode 100644
index 00000000..c6667d8b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/MacDataGenerator.java
@@ -0,0 +1,49 @@
+package org.spongycastle.pkcs;
+
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.pkcs.MacData;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.DigestInfo;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCS10CertificationRequest.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCS10CertificationRequest.java
new file mode 100644
index 00000000..c4ee749a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCS10CertificationRequest.java
@@ -0,0 +1,236 @@
+package org.spongycastle.pkcs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.pkcs.Attribute;
+import org.spongycastle.asn1.pkcs.CertificationRequest;
+import org.spongycastle.asn1.pkcs.CertificationRequestInfo;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCS10CertificationRequestBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCS10CertificationRequestBuilder.java
new file mode 100644
index 00000000..d10c6fdd
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCS10CertificationRequestBuilder.java
@@ -0,0 +1,156 @@
+package org.spongycastle.pkcs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.pkcs.Attribute;
+import org.spongycastle.asn1.pkcs.CertificationRequest;
+import org.spongycastle.asn1.pkcs.CertificationRequestInfo;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.operator.ContentSigner;
+
+/**
+ * A class for creating PKCS#10 Certification requests.
+ * <pre>
+ * 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})
+ * }
+ * </pre>
+ */
+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");
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCS12MacCalculatorBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12MacCalculatorBuilder.java
new file mode 100644
index 00000000..be82e990
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12MacCalculatorBuilder.java
@@ -0,0 +1,13 @@
+package org.spongycastle.pkcs;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.operator.OperatorCreationException;
+
+public interface PKCS12MacCalculatorBuilder
+{
+ MacCalculator build(char[] password)
+ throws OperatorCreationException;
+
+ AlgorithmIdentifier getDigestAlgorithmIdentifier();
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCS12MacCalculatorBuilderProvider.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12MacCalculatorBuilderProvider.java
new file mode 100644
index 00000000..52c9d1cd
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12MacCalculatorBuilderProvider.java
@@ -0,0 +1,8 @@
+package org.spongycastle.pkcs;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+
+public interface PKCS12MacCalculatorBuilderProvider
+{
+ PKCS12MacCalculatorBuilder get(AlgorithmIdentifier algorithmIdentifier);
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCS12PfxPdu.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12PfxPdu.java
new file mode 100644
index 00000000..6a229e48
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12PfxPdu.java
@@ -0,0 +1,161 @@
+package org.spongycastle.pkcs;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.pkcs.ContentInfo;
+import org.spongycastle.asn1.pkcs.MacData;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.pkcs.Pfx;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.CertIOException;
+import org.spongycastle.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:
+ * <pre>
+ * getEncoded(ASN1Encoding.DL)
+ * </pre>
+ * @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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCS12PfxPduBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12PfxPduBuilder.java
new file mode 100644
index 00000000..a9cb0b5b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12PfxPduBuilder.java
@@ -0,0 +1,179 @@
+package org.spongycastle.pkcs;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.DLSequence;
+import org.spongycastle.asn1.pkcs.AuthenticatedSafe;
+import org.spongycastle.asn1.pkcs.ContentInfo;
+import org.spongycastle.asn1.pkcs.MacData;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.Pfx;
+import org.spongycastle.cms.CMSEncryptedDataGenerator;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.CMSProcessableByteArray;
+import org.spongycastle.operator.OutputEncryptor;
+
+/**
+ * A builder for the PKCS#12 Pfx key and certificate store.
+ * <p>
+ * For example: you can build a basic key store for the user owning privKey as follows:
+ * </p>
+ * <pre>
+ * 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);
+ * </pre>
+ *
+ */
+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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCS12SafeBag.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12SafeBag.java
new file mode 100644
index 00000000..0ce0887e
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12SafeBag.java
@@ -0,0 +1,93 @@
+package org.spongycastle.pkcs;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.pkcs.Attribute;
+import org.spongycastle.asn1.pkcs.CRLBag;
+import org.spongycastle.asn1.pkcs.CertBag;
+import org.spongycastle.asn1.pkcs.EncryptedPrivateKeyInfo;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.pkcs.SafeBag;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.CertificateList;
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCS12SafeBagBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12SafeBagBuilder.java
new file mode 100644
index 00000000..d60bd5a5
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12SafeBagBuilder.java
@@ -0,0 +1,76 @@
+package org.spongycastle.pkcs;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.pkcs.Attribute;
+import org.spongycastle.asn1.pkcs.CertBag;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.pkcs.SafeBag;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.asn1.x509.CertificateList;
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.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)));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCS12SafeBagFactory.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12SafeBagFactory.java
new file mode 100644
index 00000000..36f53723
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCS12SafeBagFactory.java
@@ -0,0 +1,58 @@
+package org.spongycastle.pkcs;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.pkcs.ContentInfo;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.SafeBag;
+import org.spongycastle.cms.CMSEncryptedData;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.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.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCS8EncryptedPrivateKeyInfo.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCS8EncryptedPrivateKeyInfo.java
new file mode 100644
index 00000000..1f41fb67
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCS8EncryptedPrivateKeyInfo.java
@@ -0,0 +1,76 @@
+package org.spongycastle.pkcs;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.pkcs.EncryptedPrivateKeyInfo;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.cert.CertIOException;
+import org.spongycastle.operator.InputDecryptor;
+import org.spongycastle.operator.InputDecryptorProvider;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCS8EncryptedPrivateKeyInfoBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCS8EncryptedPrivateKeyInfoBuilder.java
new file mode 100644
index 00000000..3897c40a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCS8EncryptedPrivateKeyInfoBuilder.java
@@ -0,0 +1,54 @@
+package org.spongycastle.pkcs;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.pkcs.EncryptedPrivateKeyInfo;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.operator.OutputEncryptor;
+
+/**
+ * A class for creating EncryptedPrivateKeyInfo structures.
+ * <pre>
+ * EncryptedPrivateKeyInfo ::= SEQUENCE {
+ * encryptionAlgorithm AlgorithmIdentifier {{KeyEncryptionAlgorithms}},
+ * encryptedData EncryptedData
+ * }
+ *
+ * EncryptedData ::= OCTET STRING
+ *
+ * KeyEncryptionAlgorithms ALGORITHM-IDENTIFIER ::= {
+ * ... -- For local profiles
+ * }
+ * </pre>
+ */
+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");
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCSException.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCSException.java
new file mode 100644
index 00000000..201dde93
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCSException.java
@@ -0,0 +1,27 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/PKCSIOException.java b/pkix/src/main/java/org/spongycastle/pkcs/PKCSIOException.java
new file mode 100644
index 00000000..0352829b
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/PKCSIOException.java
@@ -0,0 +1,29 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS10CertificationRequest.java b/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS10CertificationRequest.java
new file mode 100644
index 00000000..6ac22464
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS10CertificationRequest.java
@@ -0,0 +1,42 @@
+package org.spongycastle.pkcs.bc;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.pkcs.CertificationRequest;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.crypto.util.PublicKeyFactory;
+import org.spongycastle.pkcs.PKCS10CertificationRequest;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java
new file mode 100644
index 00000000..1590a663
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS10CertificationRequestBuilder.java
@@ -0,0 +1,28 @@
+package org.spongycastle.pkcs.bc;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.crypto.params.AsymmetricKeyParameter;
+import org.spongycastle.crypto.util.SubjectPublicKeyInfoFactory;
+import org.spongycastle.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));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java
new file mode 100644
index 00000000..456d5b08
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12MacCalculatorBuilder.java
@@ -0,0 +1,54 @@
+package org.spongycastle.pkcs.bc;
+
+import java.security.SecureRandom;
+
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.ExtendedDigest;
+import org.spongycastle.crypto.digests.SHA1Digest;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java b/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java
new file mode 100644
index 00000000..d5533753
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12MacCalculatorBuilderProvider.java
@@ -0,0 +1,40 @@
+package org.spongycastle.pkcs.bc;
+
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.bc.BcDigestProvider;
+import org.spongycastle.pkcs.PKCS12MacCalculatorBuilder;
+import org.spongycastle.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);
+ }
+ };
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java
new file mode 100644
index 00000000..a4618c04
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12PBEInputDecryptorProviderBuilder.java
@@ -0,0 +1,66 @@
+package org.spongycastle.pkcs.bc;
+
+import java.io.InputStream;
+
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.ExtendedDigest;
+import org.spongycastle.crypto.digests.SHA1Digest;
+import org.spongycastle.crypto.generators.PKCS12ParametersGenerator;
+import org.spongycastle.crypto.io.CipherInputStream;
+import org.spongycastle.crypto.paddings.PaddedBufferedBlockCipher;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.InputDecryptor;
+import org.spongycastle.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));
+ }
+ };
+ }
+ };
+
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java
new file mode 100644
index 00000000..d8af97c3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/bc/BcPKCS12PBEOutputEncryptorBuilder.java
@@ -0,0 +1,77 @@
+package org.spongycastle.pkcs.bc;
+
+import java.io.OutputStream;
+import java.security.SecureRandom;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.BlockCipher;
+import org.spongycastle.crypto.BufferedBlockCipher;
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.ExtendedDigest;
+import org.spongycastle.crypto.digests.SHA1Digest;
+import org.spongycastle.crypto.generators.PKCS12ParametersGenerator;
+import org.spongycastle.crypto.io.CipherOutputStream;
+import org.spongycastle.crypto.paddings.PKCS7Padding;
+import org.spongycastle.crypto.paddings.PaddedBufferedBlockCipher;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.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));
+ }
+ };
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/bc/PKCS12PBEUtils.java b/pkix/src/main/java/org/spongycastle/pkcs/bc/PKCS12PBEUtils.java
new file mode 100644
index 00000000..52f07a54
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/bc/PKCS12PBEUtils.java
@@ -0,0 +1,153 @@
+package org.spongycastle.pkcs.bc;
+
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.BlockCipher;
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.ExtendedDigest;
+import org.spongycastle.crypto.engines.DESedeEngine;
+import org.spongycastle.crypto.engines.RC2Engine;
+import org.spongycastle.crypto.generators.PKCS12ParametersGenerator;
+import org.spongycastle.crypto.io.MacOutputStream;
+import org.spongycastle.crypto.macs.HMac;
+import org.spongycastle.crypto.modes.CBCBlockCipher;
+import org.spongycastle.crypto.paddings.PKCS7Padding;
+import org.spongycastle.crypto.paddings.PaddedBufferedBlockCipher;
+import org.spongycastle.crypto.params.DESedeParameters;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.crypto.params.ParametersWithIV;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java
new file mode 100644
index 00000000..8f0e20cf
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequest.java
@@ -0,0 +1,115 @@
+package org.spongycastle.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.spongycastle.asn1.pkcs.CertificationRequest;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.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());
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java
new file mode 100644
index 00000000..0efa5fa2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java
@@ -0,0 +1,38 @@
+package org.spongycastle.pkcs.jcajce;
+
+import java.security.PublicKey;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS12SafeBagBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS12SafeBagBuilder.java
new file mode 100644
index 00000000..f8c06f7c
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS12SafeBagBuilder.java
@@ -0,0 +1,45 @@
+package org.spongycastle.pkcs.jcajce;
+
+import java.io.IOException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.x509.Certificate;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.pkcs.PKCS12SafeBagBuilder;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS8EncryptedPrivateKeyInfoBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS8EncryptedPrivateKeyInfoBuilder.java
new file mode 100644
index 00000000..f8a5856c
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcaPKCS8EncryptedPrivateKeyInfoBuilder.java
@@ -0,0 +1,15 @@
+package org.spongycastle.pkcs.jcajce;
+
+import java.security.PrivateKey;
+
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.pkcs.PKCS8EncryptedPrivateKeyInfoBuilder;
+
+public class JcaPKCS8EncryptedPrivateKeyInfoBuilder
+ extends PKCS8EncryptedPrivateKeyInfoBuilder
+{
+ public JcaPKCS8EncryptedPrivateKeyInfoBuilder(PrivateKey privateKey)
+ {
+ super(PrivateKeyInfo.getInstance(privateKey.getEncoded()));
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilder.java
new file mode 100644
index 00000000..25b8da06
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilder.java
@@ -0,0 +1,122 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.ExtendedDigest;
+import org.spongycastle.crypto.generators.PKCS12ParametersGenerator;
+import org.spongycastle.jcajce.io.MacOutputStream;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilderProvider.java b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilderProvider.java
new file mode 100644
index 00000000..6c9c3023
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCS12MacCalculatorBuilderProvider.java
@@ -0,0 +1,108 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.generators.PKCS12ParametersGenerator;
+import org.spongycastle.jcajce.io.MacOutputStream;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.MacCalculator;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.pkcs.PKCS12MacCalculatorBuilder;
+import org.spongycastle.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);
+ }
+ };
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java
new file mode 100644
index 00000000..5f5413ca
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCSPBEInputDecryptorProviderBuilder.java
@@ -0,0 +1,177 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.cryptopro.GOST28147Parameters;
+import org.spongycastle.asn1.pkcs.PBES2Parameters;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.provider.symmetric.util.BCPBEKey;
+import org.spongycastle.jcajce.spec.GOST28147ParameterSpec;
+import org.spongycastle.jcajce.spec.PBKDF2KeySpec;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.DefaultSecretKeySizeProvider;
+import org.spongycastle.operator.InputDecryptor;
+import org.spongycastle.operator.InputDecryptorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.SecretKeySizeProvider;
+
+public class JcePKCSPBEInputDecryptorProviderBuilder
+{
+ private JcaJceHelper helper = new DefaultJcaJceHelper();
+ private boolean wrongPKCS12Zero = false;
+ private SecretKeySizeProvider keySizeProvider = DefaultSecretKeySizeProvider.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());
+
+ if (func.isDefaultPrf())
+ {
+ key = keyFact.generateSecret(new PBEKeySpec(password, func.getSalt(), func.getIterationCount().intValue(), keySizeProvider.getKeySize(encScheme)));
+ }
+ else
+ {
+ key = keyFact.generateSecret(new PBKDF2KeySpec(password, func.getSalt(), func.getIterationCount().intValue(), keySizeProvider.getKeySize(encScheme), func.getPrf()));
+ }
+
+ cipher = helper.createCipher(alg.getEncryptionScheme().getAlgorithm().getId());
+
+ encryptionAlg = AlgorithmIdentifier.getInstance(alg.getEncryptionScheme());
+
+ ASN1Encodable encParams = alg.getEncryptionScheme().getParameters();
+ if (encParams instanceof ASN1OctetString)
+ {
+ cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ASN1OctetString.getInstance(encParams).getOctets()));
+ }
+ else
+ {
+ // TODO: at the moment it's just GOST, but...
+ GOST28147Parameters gParams = GOST28147Parameters.getInstance(encParams);
+
+ cipher.init(Cipher.DECRYPT_MODE, key, new GOST28147ParameterSpec(gParams.getEncryptionParamSet(), gParams.getIV()));
+ }
+ }
+ }
+ 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);
+ }
+ };
+ }
+ };
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java
new file mode 100644
index 00000000..9ab806ef
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/pkcs/jcajce/JcePKCSPBEOutputEncryptorBuilder.java
@@ -0,0 +1,179 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.bc.BCObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.EncryptionScheme;
+import org.spongycastle.asn1.pkcs.KeyDerivationFunc;
+import org.spongycastle.asn1.pkcs.PBES2Parameters;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.PBEParametersGenerator;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.DefaultSecretKeySizeProvider;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.operator.SecretKeySizeProvider;
+
+public class JcePKCSPBEOutputEncryptorBuilder
+{
+ private JcaJceHelper helper = new DefaultJcaJceHelper();
+ private ASN1ObjectIdentifier algorithm;
+ private ASN1ObjectIdentifier keyEncAlgorithm;
+ private SecureRandom random;
+ private SecretKeySizeProvider keySizeProvider = DefaultSecretKeySizeProvider.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/GenTimeAccuracy.java b/pkix/src/main/java/org/spongycastle/tsp/GenTimeAccuracy.java
new file mode 100644
index 00000000..bb042e90
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/GenTimeAccuracy.java
@@ -0,0 +1,60 @@
+package org.spongycastle.tsp;
+
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.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(
+ ASN1Integer 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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TSPAlgorithms.java b/pkix/src/main/java/org/spongycastle/tsp/TSPAlgorithms.java
new file mode 100644
index 00000000..fa5c6f06
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TSPAlgorithms.java
@@ -0,0 +1,35 @@
+package org.spongycastle.tsp;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.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 }));
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TSPException.java b/pkix/src/main/java/org/spongycastle/tsp/TSPException.java
new file mode 100644
index 00000000..6125ceff
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TSPException.java
@@ -0,0 +1,28 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TSPIOException.java b/pkix/src/main/java/org/spongycastle/tsp/TSPIOException.java
new file mode 100644
index 00000000..418ff1b2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TSPIOException.java
@@ -0,0 +1,30 @@
+package org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TSPUtil.java b/pkix/src/main/java/org/spongycastle/tsp/TSPUtil.java
new file mode 100644
index 00000000..23a0454c
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TSPUtil.java
@@ -0,0 +1,209 @@
+package org.spongycastle.tsp;
+
+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.List;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.cms.Attribute;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.asn1.x509.ExtendedKeyUsage;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.asn1.x509.ExtensionsGenerator;
+import org.spongycastle.asn1.x509.KeyPurposeId;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cms.SignerInformation;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.Integers;
+
+public class TSPUtil
+{
+ 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 certificate 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.");
+ }
+ }
+
+ 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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TSPValidationException.java b/pkix/src/main/java/org/spongycastle/tsp/TSPValidationException.java
new file mode 100644
index 00000000..f89ac6c1
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TSPValidationException.java
@@ -0,0 +1,34 @@
+package org.spongycastle.tsp;
+
+/**
+ * Exception thrown if a TSP request or response fails to validate.
+ * <p>
+ * 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TimeStampRequest.java b/pkix/src/main/java/org/spongycastle/tsp/TimeStampRequest.java
new file mode 100644
index 00000000..54ed40ec
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TimeStampRequest.java
@@ -0,0 +1,267 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cmp.PKIFailureInfo;
+import org.spongycastle.asn1.tsp.TimeStampReq;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.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
+ {
+ this(loadRequest(in));
+ }
+
+ private static TimeStampReq loadRequest(InputStream in)
+ throws IOException
+ {
+ try
+ {
+ return 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 = ((ASN1ObjectIdentifier)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);
+ }
+
+ /**
+ * 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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TimeStampRequestGenerator.java b/pkix/src/main/java/org/spongycastle/tsp/TimeStampRequestGenerator.java
new file mode 100644
index 00000000..382b366a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TimeStampRequestGenerator.java
@@ -0,0 +1,163 @@
+package org.spongycastle.tsp;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+import org.spongycastle.asn1.ASN1Boolean;
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.tsp.MessageImprint;
+import org.spongycastle.asn1.tsp.TimeStampReq;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.Extensions;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TimeStampResponse.java b/pkix/src/main/java/org/spongycastle/tsp/TimeStampResponse.java
new file mode 100644
index 00000000..cc327f45
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TimeStampResponse.java
@@ -0,0 +1,189 @@
+package org.spongycastle.tsp;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.cmp.PKIFailureInfo;
+import org.spongycastle.asn1.cmp.PKIFreeText;
+import org.spongycastle.asn1.cmp.PKIStatus;
+import org.spongycastle.asn1.cms.Attribute;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.tsp.TimeStampResp;
+import org.spongycastle.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();
+ }
+} \ No newline at end of file
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TimeStampResponseGenerator.java b/pkix/src/main/java/org/spongycastle/tsp/TimeStampResponseGenerator.java
new file mode 100644
index 00000000..57e83aa2
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TimeStampResponseGenerator.java
@@ -0,0 +1,353 @@
+package org.spongycastle.tsp;
+
+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.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.DERUTF8String;
+import org.spongycastle.asn1.cmp.PKIFailureInfo;
+import org.spongycastle.asn1.cmp.PKIFreeText;
+import org.spongycastle.asn1.cmp.PKIStatus;
+import org.spongycastle.asn1.cmp.PKIStatusInfo;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.tsp.TimeStampResp;
+
+/**
+ * Generator for RFC 3161 Time Stamp Responses.
+ * <p>
+ * 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.
+ * </p>
+ * If you're after the most control with generating a response use:
+ * <pre>
+ * TimeStampResponse tsResp;
+ *
+ * try
+ * {
+ * tsResp = tsRespGen.generateGrantedResponse(request, new BigInteger("23"), new Date());
+ * }
+ * catch (Exception e)
+ * {
+ * tsResp = tsRespGen.generateRejectedResponse(e);
+ * }
+ * </pre>
+ * The generate method does this, but provides a status string of "Operation Okay".
+ * <p>
+ * 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.
+ * </p>
+ */
+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 ASN1Integer(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.
+ * <p>
+ * If genTime is null a timeNotAvailable error response will be returned. Calling generate() is the
+ * equivalent of:
+ * <pre>
+ * TimeStampResponse tsResp;
+ *
+ * try
+ * {
+ * tsResp = tsRespGen.generateGrantedResponse(request, serialNumber, genTime, "Operation Okay");
+ * }
+ * catch (Exception e)
+ * {
+ * tsResp = tsRespGen.generateRejectedResponse(e);
+ * }
+ * </pre>
+ * @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.
+ * <p>
+ * 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.
+ * </p>
+ * @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.
+ * <p>
+ * 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.
+ * </p>
+ * @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));
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TimeStampToken.java b/pkix/src/main/java/org/spongycastle/tsp/TimeStampToken.java
new file mode 100644
index 00000000..00d2a903
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TimeStampToken.java
@@ -0,0 +1,393 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.cms.Attribute;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.IssuerAndSerialNumber;
+import org.spongycastle.asn1.ess.ESSCertID;
+import org.spongycastle.asn1.ess.ESSCertIDv2;
+import org.spongycastle.asn1.ess.SigningCertificate;
+import org.spongycastle.asn1.ess.SigningCertificateV2;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.tsp.TSTInfo;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.IssuerSerial;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.CMSProcessable;
+import org.spongycastle.cms.CMSSignedData;
+import org.spongycastle.cms.SignerId;
+import org.spongycastle.cms.SignerInformation;
+import org.spongycastle.cms.SignerInformationVerifier;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.Store;
+
+/**
+ * Carrier class for a TimeStampToken.
+ */
+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.
+ * <p>
+ * 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.
+ * </p>
+ * <p>
+ * A successful call to validate means all the above are true.
+ * </p>
+ *
+ * @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.
+ * <p>
+ * Note: this is a much weaker proof of correctness than calling validate().
+ * </p>
+ *
+ * @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();
+ }
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TimeStampTokenGenerator.java b/pkix/src/main/java/org/spongycastle/tsp/TimeStampTokenGenerator.java
new file mode 100644
index 00000000..f3783f80
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TimeStampTokenGenerator.java
@@ -0,0 +1,380 @@
+package org.spongycastle.tsp;
+
+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.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1Boolean;
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1GeneralizedTime;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.ess.ESSCertID;
+import org.spongycastle.asn1.ess.ESSCertIDv2;
+import org.spongycastle.asn1.ess.SigningCertificate;
+import org.spongycastle.asn1.ess.SigningCertificateV2;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.tsp.Accuracy;
+import org.spongycastle.asn1.tsp.MessageImprint;
+import org.spongycastle.asn1.tsp.TSTInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.IssuerSerial;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cms.CMSAttributeTableGenerationException;
+import org.spongycastle.cms.CMSAttributeTableGenerator;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.CMSProcessableByteArray;
+import org.spongycastle.cms.CMSSignedData;
+import org.spongycastle.cms.CMSSignedDataGenerator;
+import org.spongycastle.cms.SignerInfoGenerator;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.util.CollectionStore;
+import org.spongycastle.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:
+ * <pre>
+ * 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;
+ * }
+ * });
+ * </pre>
+ */
+public class TimeStampTokenGenerator
+{
+ int accuracySeconds = -1;
+
+ int accuracyMillis = -1;
+
+ int accuracyMicros = -1;
+
+ boolean ordering = false;
+
+ GeneralName tsa = null;
+
+ private ASN1ObjectIdentifier tsaPolicyOID;
+
+ private List certs = new ArrayList();
+ private List crls = new ArrayList();
+ private List attrCerts = new ArrayList();
+ private Map otherRevoc = new HashMap();
+ 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, digestCalculator, tsaPolicy, false);
+ }
+
+ /**
+ * 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.
+ * @param isIssuerSerialIncluded should issuerSerial be included in the ESSCertIDs, true if yes, by default false.
+ * @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,
+ boolean isIssuerSerialIncluded)
+ throws IllegalArgumentException, TSPException
+ {
+ this.signerInfoGen = signerInfoGen;
+ this.tsaPolicyOID = tsaPolicy;
+
+ if (!signerInfoGen.hasAssociatedCertificate())
+ {
+ throw new IllegalArgumentException("SignerInfoGenerator must have an associated certificate");
+ }
+
+ X509CertificateHolder assocCert = signerInfoGen.getAssociatedCertificate();
+ TSPUtil.validateCertificate(assocCert);
+
+ try
+ {
+ OutputStream dOut = digestCalculator.getOutputStream();
+
+ dOut.write(assocCert.getEncoded());
+
+ dOut.close();
+
+ if (digestCalculator.getAlgorithmIdentifier().getAlgorithm().equals(OIWObjectIdentifiers.idSHA1))
+ {
+ final ESSCertID essCertid = new ESSCertID(digestCalculator.getDigest(),
+ isIssuerSerialIncluded ? new IssuerSerial(new GeneralNames(new GeneralName(assocCert.getIssuer())), assocCert.getSerialNumber())
+ : null);
+
+ 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(),
+ isIssuerSerialIncluded ? new IssuerSerial(new GeneralNames(new GeneralName(assocCert.getIssuer())), new ASN1Integer(assocCert.getSerialNumber()))
+ : null);
+
+ 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));
+ }
+
+ /**
+ * Add a Store of otherRevocationData to the CRL set to be included with the generated TimeStampToken.
+ *
+ * @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)
+ {
+ otherRevoc.put(otherRevocationInfoFormat, otherRevocationInfos.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;
+ }
+
+ /**
+ * Generate a TimeStampToken for the passed in request and serialNumber marking it with the passed in genTime.
+ *
+ * @param request the originating request.
+ * @param serialNumber serial number for the TimeStampToken
+ * @param genTime token generation time.
+ * @return a TimeStampToken
+ * @throws TSPException
+ */
+ public TimeStampToken generate(
+ TimeStampRequest request,
+ BigInteger serialNumber,
+ Date genTime)
+ throws TSPException
+ {
+ 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.addAttributeCertificates(new CollectionStore(attrCerts));
+ }
+
+ signedDataGenerator.addCRLs(new CollectionStore(crls));
+
+ if (!otherRevoc.isEmpty())
+ {
+ for (Iterator it = otherRevoc.keySet().iterator(); it.hasNext();)
+ {
+ ASN1ObjectIdentifier format = (ASN1ObjectIdentifier)it.next();
+
+ signedDataGenerator.addOtherRevocationInfo(format, new CollectionStore((Collection)otherRevoc.get(format)));
+ }
+ }
+
+ 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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/TimeStampTokenInfo.java b/pkix/src/main/java/org/spongycastle/tsp/TimeStampTokenInfo.java
new file mode 100644
index 00000000..e9f70650
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/TimeStampTokenInfo.java
@@ -0,0 +1,121 @@
+package org.spongycastle.tsp;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.text.ParseException;
+import java.util.Date;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.tsp.Accuracy;
+import org.spongycastle.asn1.tsp.TSTInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedData.java b/pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedData.java
new file mode 100644
index 00000000..844f123a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedData.java
@@ -0,0 +1,204 @@
+package org.spongycastle.tsp.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.Evidence;
+import org.spongycastle.asn1.cms.TimeStampAndCRL;
+import org.spongycastle.asn1.cms.TimeStampTokenEvidence;
+import org.spongycastle.asn1.cms.TimeStampedData;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedDataGenerator.java b/pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedDataGenerator.java
new file mode 100644
index 00000000..a1ad0c0f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedDataGenerator.java
@@ -0,0 +1,70 @@
+package org.spongycastle.tsp.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.BEROctetString;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.Evidence;
+import org.spongycastle.asn1.cms.TimeStampAndCRL;
+import org.spongycastle.asn1.cms.TimeStampTokenEvidence;
+import org.spongycastle.asn1.cms.TimeStampedData;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.tsp.TimeStampToken;
+import org.spongycastle.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)))));
+ }
+}
+
diff --git a/pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java b/pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java
new file mode 100644
index 00000000..c3518b77
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java
@@ -0,0 +1,207 @@
+package org.spongycastle.tsp.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.spongycastle.asn1.BERTags;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfoParser;
+import org.spongycastle.asn1.cms.TimeStampedDataParser;
+import org.spongycastle.cms.CMSContentInfoParser;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.tsp.TimeStampToken;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java b/pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java
new file mode 100644
index 00000000..9dbeb97f
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java
@@ -0,0 +1,88 @@
+package org.spongycastle.tsp.cms;
+
+import java.net.URI;
+
+import org.spongycastle.asn1.ASN1Boolean;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.DERUTF8String;
+import org.spongycastle.asn1.cms.Attributes;
+import org.spongycastle.asn1.cms.MetaData;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/cms/ImprintDigestInvalidException.java b/pkix/src/main/java/org/spongycastle/tsp/cms/ImprintDigestInvalidException.java
new file mode 100644
index 00000000..1dfc2bb3
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/cms/ImprintDigestInvalidException.java
@@ -0,0 +1,21 @@
+package org.spongycastle.tsp.cms;
+
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/cms/MetaDataUtil.java b/pkix/src/main/java/org/spongycastle/tsp/cms/MetaDataUtil.java
new file mode 100644
index 00000000..f4ad579a
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/cms/MetaDataUtil.java
@@ -0,0 +1,76 @@
+package org.spongycastle.tsp.cms;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1String;
+import org.spongycastle.asn1.cms.Attributes;
+import org.spongycastle.asn1.cms.MetaData;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/tsp/cms/TimeStampDataUtil.java b/pkix/src/main/java/org/spongycastle/tsp/cms/TimeStampDataUtil.java
new file mode 100644
index 00000000..fd1bcc8d
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/tsp/cms/TimeStampDataUtil.java
@@ -0,0 +1,256 @@
+package org.spongycastle.tsp.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.Evidence;
+import org.spongycastle.asn1.cms.TimeStampAndCRL;
+import org.spongycastle.asn1.cms.TimeStampedData;
+import org.spongycastle.asn1.cms.TimeStampedDataParser;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.tsp.TSPException;
+import org.spongycastle.tsp.TimeStampToken;
+import org.spongycastle.tsp.TimeStampTokenInfo;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/java/org/spongycastle/voms/VOMSAttribute.java b/pkix/src/main/java/org/spongycastle/voms/VOMSAttribute.java
new file mode 100644
index 00000000..4e7aac73
--- /dev/null
+++ b/pkix/src/main/java/org/spongycastle/voms/VOMSAttribute.java
@@ -0,0 +1,242 @@
+package org.spongycastle.voms;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.x509.IetfAttrSyntax;
+import org.spongycastle.x509.X509Attribute;
+import org.spongycastle.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.<br>
+ * <b>NOTE:</b> Cryptographic signatures, time stamps etc. will <b>not</b> 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 <vo>/<host>:<port>
+ 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):<br>
+ * <code>/vo[/group[/group2...]][/Role=[role]][/Capability=capability]</code>
+ */
+ 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 <code>&lt;host&gt;:&lt;port&gt;</code>
+ * @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();
+ }
+ }
+}
diff --git a/pkix/src/main/javadoc/org/bouncycastle/cert/cmp/package.html b/pkix/src/main/javadoc/org/spongycastle/cert/cmp/package.html
index a58af189..a58af189 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/cert/cmp/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/cert/cmp/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/cert/crmf/jcajce/package.html b/pkix/src/main/javadoc/org/spongycastle/cert/crmf/jcajce/package.html
index e9bc53fd..e9bc53fd 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/cert/crmf/jcajce/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/cert/crmf/jcajce/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/cert/crmf/package.html b/pkix/src/main/javadoc/org/spongycastle/cert/crmf/package.html
index 521fc440..521fc440 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/cert/crmf/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/cert/crmf/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/cert/jcajce/package.html b/pkix/src/main/javadoc/org/spongycastle/cert/jcajce/package.html
index cc15e01a..cc15e01a 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/cert/jcajce/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/cert/jcajce/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/cert/ocsp/jcajce/package.html b/pkix/src/main/javadoc/org/spongycastle/cert/ocsp/jcajce/package.html
index cfe87f22..cfe87f22 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/cert/ocsp/jcajce/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/cert/ocsp/jcajce/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/cert/ocsp/package.html b/pkix/src/main/javadoc/org/spongycastle/cert/ocsp/package.html
index 234cb327..234cb327 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/cert/ocsp/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/cert/ocsp/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/cert/package.html b/pkix/src/main/javadoc/org/spongycastle/cert/package.html
index 1b2a3053..1b2a3053 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/cert/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/cert/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/cert/selector/package.html b/pkix/src/main/javadoc/org/spongycastle/cert/selector/package.html
index c5c42110..c5c42110 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/cert/selector/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/cert/selector/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/cms/package.html b/pkix/src/main/javadoc/org/spongycastle/cms/package.html
index 644e8620..644e8620 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/cms/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/cms/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/dvcs/package.html b/pkix/src/main/javadoc/org/spongycastle/dvcs/package.html
index aecbd708..aecbd708 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/dvcs/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/dvcs/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/eac/package.html b/pkix/src/main/javadoc/org/spongycastle/eac/package.html
index 97c41fa9..97c41fa9 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/eac/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/eac/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/mozilla/package.html b/pkix/src/main/javadoc/org/spongycastle/mozilla/package.html
index dd2203e4..dd2203e4 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/mozilla/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/mozilla/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/openssl/package.html b/pkix/src/main/javadoc/org/spongycastle/openssl/package.html
index 7e60a79e..7e60a79e 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/openssl/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/openssl/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/operator/package.html b/pkix/src/main/javadoc/org/spongycastle/operator/package.html
index b64343ad..b64343ad 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/operator/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/operator/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/pkcs/jcajce/package.html b/pkix/src/main/javadoc/org/spongycastle/pkcs/jcajce/package.html
index 9b10dc42..9b10dc42 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/pkcs/jcajce/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/pkcs/jcajce/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/pkcs/package.html b/pkix/src/main/javadoc/org/spongycastle/pkcs/package.html
index c83de7cf..c83de7cf 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/pkcs/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/pkcs/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/tsp/cms/package.html b/pkix/src/main/javadoc/org/spongycastle/tsp/cms/package.html
index 2cf1bace..2cf1bace 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/tsp/cms/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/tsp/cms/package.html
diff --git a/pkix/src/main/javadoc/org/bouncycastle/tsp/package.html b/pkix/src/main/javadoc/org/spongycastle/tsp/package.html
index 45d0c3c3..45d0c3c3 100644
--- a/pkix/src/main/javadoc/org/bouncycastle/tsp/package.html
+++ b/pkix/src/main/javadoc/org/spongycastle/tsp/package.html
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/cmp/GeneralPKIMessage.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/cmp/GeneralPKIMessage.java
deleted file mode 100644
index 08c42c7d..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/cmp/GeneralPKIMessage.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/CertificateRequestMessage.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/CertificateRequestMessage.java
deleted file mode 100644
index ae328d68..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/CertificateRequestMessage.java
+++ /dev/null
@@ -1,309 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/FixedLengthMGF1Padder.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/FixedLengthMGF1Padder.java
deleted file mode 100644
index f100cb67..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/FixedLengthMGF1Padder.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java
deleted file mode 100644
index 5af8e75b..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java
+++ /dev/null
@@ -1,134 +0,0 @@
-package org.bouncycastle.cert.crmf.bc;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.cert.crmf.EncryptedValuePadder;
-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 BcFixedLengthMGF1Padder
- 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 BcFixedLengthMGF1Padder(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 BcFixedLengthMGF1Padder(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 + nextByte(random));
- }
-
- 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;
- }
-
- private int nextByte(SecureRandom random)
- {
- int bits, val;
- do
- {
- bits = random.nextInt() & 0x7fffffff;
- val = bits % 255;
- }
- while (bits - val + 254 < 0);
-
- return val;
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/CRMFHelper.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/CRMFHelper.java
deleted file mode 100644
index 793d122a..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/CRMFHelper.java
+++ /dev/null
@@ -1,485 +0,0 @@
-package 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.util.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;
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java
deleted file mode 100644
index dd1beee2..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package org.bouncycastle.cert.crmf.jcajce;
-
-import java.io.InputStream;
-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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- };
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java
deleted file mode 100644
index a8c2967d..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java
deleted file mode 100644
index e78e175b..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.bouncycastle.cert.crmf.jcajce;
-
-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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java
deleted file mode 100644
index 6462bf57..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java
+++ /dev/null
@@ -1,149 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/path/CertPathValidationException.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/path/CertPathValidationException.java
deleted file mode 100644
index b302d8a3..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/path/CertPathValidationException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.bouncycastle.cert.path;
-
-public class CertPathValidationException
- extends Exception
-{
- private Exception cause;
-
- public CertPathValidationException(String msg)
- {
- this(msg, null);
- }
-
- public CertPathValidationException(String msg, Exception cause)
- {
- super(msg);
-
- this.cause = cause;
- }
-
- public Throwable getCause()
- {
- return cause;
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java
deleted file mode 100644
index 3570053c..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package 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());
-}
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
deleted file mode 100644
index 22a35371..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSAbsentContent.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSAbsentContent.java
deleted file mode 100644
index d23fc8c0..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSAbsentContent.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSProcessableByteArray.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSProcessableByteArray.java
deleted file mode 100644
index 8342df21..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSProcessableByteArray.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package 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 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 Arrays.clone(bytes);
- }
-
- public ASN1ObjectIdentifier getContentType()
- {
- return type;
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSProcessableFile.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSProcessableFile.java
deleted file mode 100644
index decfb38b..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSProcessableFile.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSTypedStream.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSTypedStream.java
deleted file mode 100644
index 5aa42ed0..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/CMSTypedStream.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package 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;
- }
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/OriginatorInfoGenerator.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/OriginatorInfoGenerator.java
deleted file mode 100644
index 6a5c0e9d..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/OriginatorInfoGenerator.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package 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));
- }
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/RecipientId.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/RecipientId.java
deleted file mode 100644
index 7ea1f329..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/RecipientId.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package 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();
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/SignerInfoGenerator.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/SignerInfoGenerator.java
deleted file mode 100644
index acd2665b..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/SignerInfoGenerator.java
+++ /dev/null
@@ -1,291 +0,0 @@
-package 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.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 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 int getGeneratedVersion()
- {
- return 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, 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(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, 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;
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java
deleted file mode 100644
index cc1a114c..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/EnvelopedDataHelper.java
+++ /dev/null
@@ -1,671 +0,0 @@
-package org.bouncycastle.cms.jcajce;
-
-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.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.DefaultSecretKeySizeProvider;
-import org.bouncycastle.operator.GenericKey;
-import org.bouncycastle.operator.SecretKeySizeProvider;
-import org.bouncycastle.operator.SymmetricKeyUnwrapper;
-import org.bouncycastle.operator.jcajce.JceAsymmetricKeyUnwrapper;
-
-public class EnvelopedDataHelper
-{
- protected static final SecretKeySizeProvider KEY_SIZE_PROVIDER = DefaultSecretKeySizeProvider.INSTANCE;
-
- 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");
- BASE_CIPHER_NAMES.put(PKCSObjectIdentifiers.rc4, "RC4");
-
- CIPHER_ALG_NAMES.put(CMSAlgorithm.DES_CBC, "DES/CBC/PKCS5Padding");
- CIPHER_ALG_NAMES.put(CMSAlgorithm.RC2_CBC, "RC2/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");
- CIPHER_ALG_NAMES.put(PKCSObjectIdentifiers.rc4, "RC4");
-
- 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");
- }
-
- public 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");
- }
-
- public void keySizeCheck(AlgorithmIdentifier keyAlgorithm, Key key)
- throws CMSException
- {
- int expectedKeySize = EnvelopedDataHelper.KEY_SIZE_PROVIDER.getKeySize(keyAlgorithm);
- if (expectedKeySize > 0)
- {
- byte[] keyEnc = null;
-
- try
- {
- keyEnc = key.getEncoded();
- }
- catch (Exception e)
- {
- // ignore - we're using a HSM...
- }
-
- if (keyEnc != null)
- {
- if (keyEnc.length * 8 != expectedKeySize)
- {
- throw new CMSException("Expected key size for algorithm OID not found in recipient.");
- }
- }
- }
- }
-
- 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 (Exception 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 (Exception 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 (Exception 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 (Exception e)
- {
- throw new CMSException("cannot create key pair generator: " + e.getMessage(), e);
- }
- }
-
- AlgorithmParameterGenerator createAlgorithmParameterGenerator(ASN1ObjectIdentifier algorithm)
- throws CMSException
- {
- 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 (Exception e)
- {
- throw new CMSException("cannot create key pair generator: " + e.getMessage(), e);
- }
- }
-
- public 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());
-
- CMSUtils.loadParameters(params, sParams);
-
- 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());
-
- CMSUtils.loadParameters(params, sParams);
-
- 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 (Exception 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 (Exception 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(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 CMSException("parameters generation error: " + e, e);
- }
- }
-
- return pGen.generateParameters();
- }
- catch (Exception e)
- {
- throw new CMSException("exception creating algorithm parameter generator: " + e, e);
- }
- }
-
- AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier encryptionOID, AlgorithmParameters params)
- throws CMSException
- {
- ASN1Encodable asn1Params;
- if (params != null)
- {
- asn1Params = CMSUtils.extractParameters(params);
- }
- 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 (Exception 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;
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java
deleted file mode 100644
index 52dc20e8..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package 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());
-}
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java
deleted file mode 100644
index 86f59f69..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
deleted file mode 100644
index 527b28d2..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
+++ /dev/null
@@ -1,166 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java
deleted file mode 100644
index ab77b3af..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package 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();
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java
deleted file mode 100644
index bccb9e62..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java
+++ /dev/null
@@ -1,212 +0,0 @@
-package 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");
- }
- }
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcePasswordRecipient.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcePasswordRecipient.java
deleted file mode 100644
index ac144999..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcePasswordRecipient.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package org.bouncycastle.cms.jcajce;
-
-import java.security.InvalidKeyException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.NoSuchAlgorithmException;
-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.pkcs.PBKDF2Params;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.cms.CMSException;
-import org.bouncycastle.cms.PasswordRecipient;
-import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
-import org.bouncycastle.crypto.params.KeyParameter;
-
-/**
- * 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 (InvalidAlgorithmParameterException e)
- {
- throw new CMSException("cannot process content encryption key: " + e.getMessage(), e);
- }
- }
-
- public byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
- throws CMSException
- {
- PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters());
-
- PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
-
- gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue());
-
- return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey();
- }
-
- public int getPasswordConversionScheme()
- {
- return schemeID;
- }
-
- public char[] getPassword()
- {
- return password;
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java
deleted file mode 100644
index b5bb763c..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.bouncycastle.cms.jcajce;
-
-import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
-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.pkcs.PBKDF2Params;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.cms.CMSException;
-import org.bouncycastle.cms.PasswordRecipientInfoGenerator;
-import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
-import org.bouncycastle.crypto.params.KeyParameter;
-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;
- }
-
- protected byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
- throws CMSException
- {
- PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters());
-
- PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
-
- gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue());
-
- return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey();
- }
-
- 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);
- }
- catch (InvalidKeyException e)
- {
- throw new CMSException("cannot process content encryption key: " + e.getMessage(), e);
- }
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java b/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java
deleted file mode 100644
index ff5c4518..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package 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;
- }
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java b/pkix/src/main/jdk1.1/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java
deleted file mode 100644
index efa15868..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- };
- };
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java b/pkix/src/main/jdk1.1/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java
deleted file mode 100644
index 562df125..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java
+++ /dev/null
@@ -1,240 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- };
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java b/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
deleted file mode 100644
index 0cd6eb00..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
+++ /dev/null
@@ -1,164 +0,0 @@
-package org.bouncycastle.operator.jcajce;
-
-import java.io.IOException;
-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.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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 (Exception 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();
- }
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java b/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
deleted file mode 100644
index bf9ecdbe..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
+++ /dev/null
@@ -1,311 +0,0 @@
-package org.bouncycastle.operator.jcajce;
-
-import java.io.IOException;
-import java.io.OutputStream;
-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.asn1.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
-import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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 (Exception 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);
- }
- }
- };
- }
-
- public ContentVerifierProvider build(SubjectPublicKeyInfo publicKey)
- throws OperatorCreationException
- {
- return this.build(helper.convertPublicKey(publicKey));
- }
-
- private SignatureOutputStream createSignatureStream(AlgorithmIdentifier algorithm, PublicKey publicKey)
- throws OperatorCreationException
- {
- try
- {
- Signature sig = helper.createSignature(algorithm);
-
- sig.initVerify(publicKey);
-
- return new SignatureOutputStream(sig);
- }
- catch (Exception 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);
- }
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java b/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
deleted file mode 100644
index 4848c93d..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package org.bouncycastle.operator.jcajce;
-
-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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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.
- * <p>
- * For example:
- * <pre>
- * unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
- * </pre>
- * </p>
- * @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);
- }
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java b/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java
deleted file mode 100644
index c4785b10..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java
+++ /dev/null
@@ -1,159 +0,0 @@
-package 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.ASN1Integer;
-import org.bouncycastle.asn1.DERNull;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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 ASN1ObjectIdentifier(
- "1.2.840.113549.1.9.16.3.6"), new DERNull());
- }
- 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");
- }
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/OperatorHelper.java b/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/OperatorHelper.java
deleted file mode 100644
index 3c7d4339..00000000
--- a/pkix/src/main/jdk1.1/org/bouncycastle/operator/jcajce/OperatorHelper.java
+++ /dev/null
@@ -1,477 +0,0 @@
-package org.bouncycastle.operator.jcajce;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.security.AlgorithmParameters;
-import java.security.GeneralSecurityException;
-import java.security.KeyFactory;
-import java.security.MessageDigest;
-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.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-//import java.security.spec.PSSParameterSpec;
-import java.security.spec.X509EncodedKeySpec;
-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.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.jcajce.util.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 (Exception 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 (Exception e)
- {
- throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e);
- }
- }
-
- AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)
- throws OperatorCreationException
- {
- AlgorithmParameters parameters;
-
- if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
- {
- return null;
- }
-
- try
- {
- parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
- }
- catch (NoSuchAlgorithmException e)
- {
- return null; // There's a good chance there aren't any!
- }
- catch (NoSuchProviderException e)
- {
- throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
- }
-
- try
- {
- parameters.init(cipherAlgId.getParameters().toASN1Primitive().getEncoded());
- }
- catch (IOException e)
- {
- throw new OperatorCreationException("cannot initialise algorithm parameters: " + e.getMessage(), e);
- }
-
- return parameters;
- }
-
- MessageDigest createDigest(AlgorithmIdentifier digAlgId)
- throws GeneralSecurityException
- {
- MessageDigest dig;
-
- try
- {
- 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;
- }
- }
- }
- catch (Exception ex)
- {
- throw new GeneralSecurityException(ex.toString());
- }
-
- return dig;
- }
-
- Signature createSignature(AlgorithmIdentifier sigAlgId)
- throws Exception
- {
- 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);
-
- JcaJceUtils.loadParameters(params, algorithm.getParameters());
-
- 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);
- }
- }
-
- public PublicKey convertPublicKey(SubjectPublicKeyInfo publicKeyInfo)
- throws OperatorCreationException
- {
- try
- {
- KeyFactory keyFact = helper.createKeyFactory(publicKeyInfo.getAlgorithm().getAlgorithm().getId());
-
- return keyFact.generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
- }
- catch (IOException e)
- {
- throw new OperatorCreationException("cannot get encoded form of key: " + e.getMessage(), e);
- }
- catch (NoSuchAlgorithmException e)
- {
- throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
- }
- catch (NoSuchProviderException e)
- {
- throw new OperatorCreationException("cannot find factory provider: " + e.getMessage(), e);
- }
- catch (InvalidKeySpecException e)
- {
- throw new OperatorCreationException("cannot create key factory: " + 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();
- }
-}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cert/cmp/GeneralPKIMessage.java b/pkix/src/main/jdk1.1/org/spongycastle/cert/cmp/GeneralPKIMessage.java
new file mode 100644
index 00000000..2f74fe55
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cert/cmp/GeneralPKIMessage.java
@@ -0,0 +1,82 @@
+package org.spongycastle.cert.cmp;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.cmp.PKIBody;
+import org.spongycastle.asn1.cmp.PKIHeader;
+import org.spongycastle.asn1.cmp.PKIMessage;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/CertificateRequestMessage.java b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/CertificateRequestMessage.java
new file mode 100644
index 00000000..6f582812
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/CertificateRequestMessage.java
@@ -0,0 +1,309 @@
+package org.spongycastle.cert.crmf;
+
+import java.io.IOException;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DERUTF8String;
+import org.spongycastle.asn1.crmf.AttributeTypeAndValue;
+import org.spongycastle.asn1.crmf.CRMFObjectIdentifiers;
+import org.spongycastle.asn1.crmf.CertReqMsg;
+import org.spongycastle.asn1.crmf.CertTemplate;
+import org.spongycastle.asn1.crmf.Controls;
+import org.spongycastle.asn1.crmf.PKIArchiveOptions;
+import org.spongycastle.asn1.crmf.PKMACValue;
+import org.spongycastle.asn1.crmf.POPOSigningKey;
+import org.spongycastle.asn1.crmf.ProofOfPossession;
+import org.spongycastle.cert.CertIOException;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/FixedLengthMGF1Padder.java b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/FixedLengthMGF1Padder.java
new file mode 100644
index 00000000..cfb33d62
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/FixedLengthMGF1Padder.java
@@ -0,0 +1,120 @@
+package org.spongycastle.cert.crmf;
+
+import java.security.SecureRandom;
+
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.digests.SHA1Digest;
+import org.spongycastle.crypto.generators.MGF1BytesGenerator;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java
new file mode 100644
index 00000000..eec071e1
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/bc/BcFixedLengthMGF1Padder.java
@@ -0,0 +1,134 @@
+package org.spongycastle.cert.crmf.bc;
+
+import java.security.SecureRandom;
+
+import org.spongycastle.cert.crmf.EncryptedValuePadder;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.digests.SHA1Digest;
+import org.spongycastle.crypto.generators.MGF1BytesGenerator;
+import org.spongycastle.crypto.params.MGFParameters;
+
+/**
+ * An encrypted value padder that uses MGF1 as the basis of the padding.
+ */
+public class BcFixedLengthMGF1Padder
+ 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 BcFixedLengthMGF1Padder(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 BcFixedLengthMGF1Padder(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 + nextByte(random));
+ }
+
+ 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;
+ }
+
+ private int nextByte(SecureRandom random)
+ {
+ int bits, val;
+ do
+ {
+ bits = random.nextInt() & 0x7fffffff;
+ val = bits % 255;
+ }
+ while (bits - val + 254 < 0);
+
+ return val;
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/CRMFHelper.java b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/CRMFHelper.java
new file mode 100644
index 00000000..afed7590
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/CRMFHelper.java
@@ -0,0 +1,485 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Null;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DERBitString;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.iana.IANAObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.cms.CMSEnvelopedDataGenerator;
+import org.spongycastle.jcajce.util.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;
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java
new file mode 100644
index 00000000..0cf87509
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/JceAsymmetricValueDecryptorGenerator.java
@@ -0,0 +1,120 @@
+package org.spongycastle.cert.crmf.jcajce;
+
+import java.io.InputStream;
+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.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.cert.crmf.ValueDecryptorGenerator;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.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);
+ }
+ };
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java
new file mode 100644
index 00000000..5be72f2a
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java
@@ -0,0 +1,140 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java
new file mode 100644
index 00000000..6c593709
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cert/crmf/jcajce/JcePKMACValuesCalculator.java
@@ -0,0 +1,69 @@
+package org.spongycastle.cert.crmf.jcajce;
+
+import java.security.MessageDigest;
+import java.security.Provider;
+import java.security.InvalidKeyException;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.cert.crmf.PKMACValuesCalculator;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.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);
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java b/pkix/src/main/jdk1.1/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java
new file mode 100644
index 00000000..63b14ff7
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java
@@ -0,0 +1,149 @@
+package org.spongycastle.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.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cert/path/CertPathValidationException.java b/pkix/src/main/jdk1.1/org/spongycastle/cert/path/CertPathValidationException.java
new file mode 100644
index 00000000..d0cbf607
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cert/path/CertPathValidationException.java
@@ -0,0 +1,24 @@
+package org.spongycastle.cert.path;
+
+public class CertPathValidationException
+ extends Exception
+{
+ private Exception cause;
+
+ public CertPathValidationException(String msg)
+ {
+ this(msg, null);
+ }
+
+ public CertPathValidationException(String msg, Exception cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java b/pkix/src/main/jdk1.1/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java
new file mode 100644
index 00000000..8bda2e46
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java
@@ -0,0 +1,34 @@
+package org.spongycastle.cert.selector.jcajce;
+
+import java.security.cert.X509CertSelector;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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());
+}
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.1/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
new file mode 100644
index 00000000..6dbcef43
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
@@ -0,0 +1,57 @@
+package org.spongycastle.cert.selector.jcajce;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.X509CertSelector;
+
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/CMSAbsentContent.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/CMSAbsentContent.java
new file mode 100644
index 00000000..e1d7e586
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/CMSAbsentContent.java
@@ -0,0 +1,49 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/CMSProcessableByteArray.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/CMSProcessableByteArray.java
new file mode 100644
index 00000000..6ac965c7
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/CMSProcessableByteArray.java
@@ -0,0 +1,55 @@
+package org.spongycastle.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.util.Arrays;
+
+/**
+ * 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 Arrays.clone(bytes);
+ }
+
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return type;
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/CMSProcessableFile.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/CMSProcessableFile.java
new file mode 100644
index 00000000..87b7c4e9
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/CMSProcessableFile.java
@@ -0,0 +1,80 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/CMSTypedStream.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/CMSTypedStream.java
new file mode 100644
index 00000000..82466af7
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/CMSTypedStream.java
@@ -0,0 +1,86 @@
+package org.spongycastle.cms;
+
+import java.io.BufferedInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.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;
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/OriginatorInfoGenerator.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/OriginatorInfoGenerator.java
new file mode 100644
index 00000000..b6cfdd0b
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/OriginatorInfoGenerator.java
@@ -0,0 +1,54 @@
+package org.spongycastle.cms;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.spongycastle.asn1.cms.OriginatorInfo;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.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));
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/RecipientId.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/RecipientId.java
new file mode 100644
index 00000000..f2dd5dff
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/RecipientId.java
@@ -0,0 +1,31 @@
+package org.spongycastle.cms;
+
+import org.spongycastle.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();
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/SignerInfoGenerator.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/SignerInfoGenerator.java
new file mode 100644
index 00000000..47028b99
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/SignerInfoGenerator.java
@@ -0,0 +1,291 @@
+package org.spongycastle.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Set;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSet;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.SignerIdentifier;
+import org.spongycastle.asn1.cms.SignerInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DigestAlgorithmIdentifierFinder;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.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 int getGeneratedVersion()
+ {
+ return 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, 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(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, 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;
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/EnvelopedDataHelper.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/EnvelopedDataHelper.java
new file mode 100644
index 00000000..56f6f2f2
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/EnvelopedDataHelper.java
@@ -0,0 +1,671 @@
+package org.spongycastle.cms.jcajce;
+
+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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1Null;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RC2CBCParameter;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.cms.CMSEnvelopedDataGenerator;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DefaultSecretKeySizeProvider;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.SecretKeySizeProvider;
+import org.spongycastle.operator.SymmetricKeyUnwrapper;
+import org.spongycastle.operator.jcajce.JceAsymmetricKeyUnwrapper;
+
+public class EnvelopedDataHelper
+{
+ protected static final SecretKeySizeProvider KEY_SIZE_PROVIDER = DefaultSecretKeySizeProvider.INSTANCE;
+
+ 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");
+ BASE_CIPHER_NAMES.put(PKCSObjectIdentifiers.rc4, "RC4");
+
+ CIPHER_ALG_NAMES.put(CMSAlgorithm.DES_CBC, "DES/CBC/PKCS5Padding");
+ CIPHER_ALG_NAMES.put(CMSAlgorithm.RC2_CBC, "RC2/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");
+ CIPHER_ALG_NAMES.put(PKCSObjectIdentifiers.rc4, "RC4");
+
+ 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");
+ }
+
+ public 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");
+ }
+
+ public void keySizeCheck(AlgorithmIdentifier keyAlgorithm, Key key)
+ throws CMSException
+ {
+ int expectedKeySize = EnvelopedDataHelper.KEY_SIZE_PROVIDER.getKeySize(keyAlgorithm);
+ if (expectedKeySize > 0)
+ {
+ byte[] keyEnc = null;
+
+ try
+ {
+ keyEnc = key.getEncoded();
+ }
+ catch (Exception e)
+ {
+ // ignore - we're using a HSM...
+ }
+
+ if (keyEnc != null)
+ {
+ if (keyEnc.length * 8 != expectedKeySize)
+ {
+ throw new CMSException("Expected key size for algorithm OID not found in recipient.");
+ }
+ }
+ }
+ }
+
+ 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 (Exception 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 (Exception 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 (Exception 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 (Exception e)
+ {
+ throw new CMSException("cannot create key pair generator: " + e.getMessage(), e);
+ }
+ }
+
+ AlgorithmParameterGenerator createAlgorithmParameterGenerator(ASN1ObjectIdentifier algorithm)
+ throws CMSException
+ {
+ 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 (Exception e)
+ {
+ throw new CMSException("cannot create key pair generator: " + e.getMessage(), e);
+ }
+ }
+
+ public 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());
+
+ CMSUtils.loadParameters(params, sParams);
+
+ 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());
+
+ CMSUtils.loadParameters(params, sParams);
+
+ 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 (Exception 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 (Exception 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(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 CMSException("parameters generation error: " + e, e);
+ }
+ }
+
+ return pGen.generateParameters();
+ }
+ catch (Exception e)
+ {
+ throw new CMSException("exception creating algorithm parameter generator: " + e, e);
+ }
+ }
+
+ AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier encryptionOID, AlgorithmParameters params)
+ throws CMSException
+ {
+ ASN1Encodable asn1Params;
+ if (params != null)
+ {
+ asn1Params = CMSUtils.extractParameters(params);
+ }
+ 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 (Exception 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;
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcaSelectorConverter.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcaSelectorConverter.java
new file mode 100644
index 00000000..6f022467
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcaSelectorConverter.java
@@ -0,0 +1,54 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.cert.X509CertSelector;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cms.KeyTransRecipientId;
+import org.spongycastle.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());
+}
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java
new file mode 100644
index 00000000..ceb138ed
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java
@@ -0,0 +1,24 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.cert.X509CertSelector;
+
+import org.spongycastle.cms.KeyTransRecipientId;
+import org.spongycastle.cms.SignerId;
+
+public class JcaX509CertSelectorConverter
+ extends org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
new file mode 100644
index 00000000..b4bdd4ad
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
@@ -0,0 +1,166 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JceKeyAgreeRecipient.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JceKeyAgreeRecipient.java
new file mode 100644
index 00000000..93c11b21
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JceKeyAgreeRecipient.java
@@ -0,0 +1,184 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.cms.ecc.MQVuserKeyingMaterial;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cms.CMSEnvelopedGenerator;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.KeyAgreeRecipient;
+import org.spongycastle.jce.spec.MQVPrivateKeySpec;
+import org.spongycastle.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();
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java
new file mode 100644
index 00000000..b3782884
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java
@@ -0,0 +1,212 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.cms.KeyAgreeRecipientIdentifier;
+import org.spongycastle.asn1.cms.RecipientEncryptedKey;
+import org.spongycastle.asn1.cms.RecipientKeyIdentifier;
+import org.spongycastle.asn1.cms.ecc.MQVuserKeyingMaterial;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.cms.CMSEnvelopedGenerator;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.KeyAgreeRecipientInfoGenerator;
+import org.spongycastle.jce.interfaces.ECPublicKey;
+import org.spongycastle.jce.spec.ECParameterSpec;
+import org.spongycastle.jce.spec.MQVPrivateKeySpec;
+import org.spongycastle.jce.spec.MQVPublicKeySpec;
+import org.spongycastle.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");
+ }
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcePasswordRecipient.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcePasswordRecipient.java
new file mode 100644
index 00000000..31e8729b
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcePasswordRecipient.java
@@ -0,0 +1,107 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.InvalidKeyException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Key;
+import java.security.Provider;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.PasswordRecipient;
+import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
+import org.spongycastle.crypto.params.KeyParameter;
+
+/**
+ * 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 (InvalidAlgorithmParameterException e)
+ {
+ throw new CMSException("cannot process content encryption key: " + e.getMessage(), e);
+ }
+ }
+
+ public byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
+ throws CMSException
+ {
+ PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters());
+
+ PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
+
+ gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue());
+
+ return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey();
+ }
+
+ public int getPasswordConversionScheme()
+ {
+ return schemeID;
+ }
+
+ public char[] getPassword()
+ {
+ return password;
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java
new file mode 100644
index 00000000..ae706b10
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/JcePasswordRecipientInfoGenerator.java
@@ -0,0 +1,81 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.Provider;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.PasswordRecipientInfoGenerator;
+import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.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;
+ }
+
+ protected byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
+ throws CMSException
+ {
+ PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters());
+
+ PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
+
+ gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue());
+
+ return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey();
+ }
+
+ 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);
+ }
+ catch (InvalidKeyException e)
+ {
+ throw new CMSException("cannot process content encryption key: " + e.getMessage(), e);
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/ZlibExpanderProvider.java b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/ZlibExpanderProvider.java
new file mode 100644
index 00000000..880dc2ce
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/cms/jcajce/ZlibExpanderProvider.java
@@ -0,0 +1,113 @@
+package org.spongycastle.cms.jcajce;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.InflaterInputStream;
+
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.InputExpander;
+import org.spongycastle.operator.InputExpanderProvider;
+import org.spongycastle.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;
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java b/pkix/src/main/jdk1.1/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java
new file mode 100644
index 00000000..bd0e93f2
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8DecryptorProviderBuilder.java
@@ -0,0 +1,156 @@
+package org.spongycastle.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.spongycastle.asn1.pkcs.KeyDerivationFunc;
+import org.spongycastle.asn1.pkcs.EncryptionScheme;
+import org.spongycastle.asn1.pkcs.PBEParameter;
+import org.spongycastle.asn1.pkcs.PBES2Parameters;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.openssl.PEMException;
+import org.spongycastle.operator.InputDecryptor;
+import org.spongycastle.operator.InputDecryptorProvider;
+import org.spongycastle.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);
+ }
+ };
+ };
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java b/pkix/src/main/jdk1.1/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java
new file mode 100644
index 00000000..139d6fcc
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java
@@ -0,0 +1,240 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.KeyDerivationFunc;
+import org.spongycastle.asn1.pkcs.PBES2Parameters;
+import org.spongycastle.asn1.pkcs.PBKDF2Params;
+import org.spongycastle.asn1.pkcs.PKCS12PBEParams;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.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);
+ }
+ };
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JcaContentSignerBuilder.java b/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JcaContentSignerBuilder.java
new file mode 100644
index 00000000..9f88073e
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JcaContentSignerBuilder.java
@@ -0,0 +1,164 @@
+package org.spongycastle.operator.jcajce;
+
+import java.io.IOException;
+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.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.ContentSigner;
+import org.spongycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.OperatorStreamException;
+import org.spongycastle.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 (Exception 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();
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java b/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
new file mode 100644
index 00000000..82ddae47
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java
@@ -0,0 +1,311 @@
+package org.spongycastle.operator.jcajce;
+
+import java.io.IOException;
+import java.io.OutputStream;
+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.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.jcajce.JcaX509CertificateHolder;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.ContentVerifier;
+import org.spongycastle.operator.ContentVerifierProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.operator.OperatorStreamException;
+import org.spongycastle.operator.RawContentVerifier;
+import org.spongycastle.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 (Exception 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);
+ }
+ }
+ };
+ }
+
+ public ContentVerifierProvider build(SubjectPublicKeyInfo publicKey)
+ throws OperatorCreationException
+ {
+ return this.build(helper.convertPublicKey(publicKey));
+ }
+
+ private SignatureOutputStream createSignatureStream(AlgorithmIdentifier algorithm, PublicKey publicKey)
+ throws OperatorCreationException
+ {
+ try
+ {
+ Signature sig = helper.createSignature(algorithm);
+
+ sig.initVerify(publicKey);
+
+ return new SignatureOutputStream(sig);
+ }
+ catch (Exception 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);
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java b/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
new file mode 100644
index 00000000..29f7fb3d
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JceAsymmetricKeyUnwrapper.java
@@ -0,0 +1,127 @@
+package org.spongycastle.operator.jcajce;
+
+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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.AsymmetricKeyUnwrapper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.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.
+ * <p>
+ * For example:
+ * <pre>
+ * unwrapper.setAlgorithmMapping(PKCSObjectIdentifiers.rsaEncryption, "RSA");
+ * </pre>
+ * </p>
+ * @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);
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JceSymmetricKeyWrapper.java b/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JceSymmetricKeyWrapper.java
new file mode 100644
index 00000000..2fd2f97c
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/JceSymmetricKeyWrapper.java
@@ -0,0 +1,159 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OperatorException;
+import org.spongycastle.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 ASN1ObjectIdentifier(
+ "1.2.840.113549.1.9.16.3.6"), new DERNull());
+ }
+ 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");
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/OperatorHelper.java b/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/OperatorHelper.java
new file mode 100644
index 00000000..8507d878
--- /dev/null
+++ b/pkix/src/main/jdk1.1/org/spongycastle/operator/jcajce/OperatorHelper.java
@@ -0,0 +1,477 @@
+package org.spongycastle.operator.jcajce;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+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.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+//import java.security.spec.PSSParameterSpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RSASSAPSSparams;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.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 (Exception 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 (Exception e)
+ {
+ throw new OperatorCreationException("cannot create cipher: " + e.getMessage(), e);
+ }
+ }
+
+ AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)
+ throws OperatorCreationException
+ {
+ AlgorithmParameters parameters;
+
+ if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
+ {
+ return null;
+ }
+
+ try
+ {
+ parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ return null; // There's a good chance there aren't any!
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
+ }
+
+ try
+ {
+ parameters.init(cipherAlgId.getParameters().toASN1Primitive().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("cannot initialise algorithm parameters: " + e.getMessage(), e);
+ }
+
+ return parameters;
+ }
+
+ MessageDigest createDigest(AlgorithmIdentifier digAlgId)
+ throws GeneralSecurityException
+ {
+ MessageDigest dig;
+
+ try
+ {
+ 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;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new GeneralSecurityException(ex.toString());
+ }
+
+ return dig;
+ }
+
+ Signature createSignature(AlgorithmIdentifier sigAlgId)
+ throws Exception
+ {
+ 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);
+
+ JcaJceUtils.loadParameters(params, algorithm.getParameters());
+
+ 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);
+ }
+ }
+
+ public PublicKey convertPublicKey(SubjectPublicKeyInfo publicKeyInfo)
+ throws OperatorCreationException
+ {
+ try
+ {
+ KeyFactory keyFact = helper.createKeyFactory(publicKeyInfo.getAlgorithm().getAlgorithm().getId());
+
+ return keyFact.generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("cannot get encoded form of key: " + e.getMessage(), e);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot find factory provider: " + e.getMessage(), e);
+ }
+ catch (InvalidKeySpecException e)
+ {
+ throw new OperatorCreationException("cannot create key factory: " + 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();
+ }
+}
diff --git a/pkix/src/main/jdk1.2/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java b/pkix/src/main/jdk1.2/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java
deleted file mode 100644
index a946945e..00000000
--- a/pkix/src/main/jdk1.2/org/bouncycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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);
- }
- }
-}
diff --git a/pkix/src/main/jdk1.2/org/bouncycastle/cert/jcajce/JcaAttrCertStore.java b/pkix/src/main/jdk1.2/org/bouncycastle/cert/jcajce/JcaAttrCertStore.java
deleted file mode 100644
index e3158c03..00000000
--- a/pkix/src/main/jdk1.2/org/bouncycastle/cert/jcajce/JcaAttrCertStore.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package 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.
- * <p>
- * The class will convert X509AttributeCertificate objects into X509AttributeCertificateHolder objects.
- * </p>
- */
-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;
- }
-}
diff --git a/pkix/src/main/jdk1.2/org/bouncycastle/cms/bc/BcCMSContentEncryptorBuilder.java b/pkix/src/main/jdk1.2/org/bouncycastle/cms/bc/BcCMSContentEncryptorBuilder.java
deleted file mode 100644
index 5d1a2a66..00000000
--- a/pkix/src/main/jdk1.2/org/bouncycastle/cms/bc/BcCMSContentEncryptorBuilder.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package 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());
- }
- }
-}
diff --git a/pkix/src/main/jdk1.2/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java b/pkix/src/main/jdk1.2/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
deleted file mode 100644
index 44318935..00000000
--- a/pkix/src/main/jdk1.2/org/bouncycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/jdk1.2/org/bouncycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java b/pkix/src/main/jdk1.2/org/bouncycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java
deleted file mode 100644
index 247afd1a..00000000
--- a/pkix/src/main/jdk1.2/org/bouncycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java
+++ /dev/null
@@ -1,155 +0,0 @@
-package 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;
- }
- }
- }
-}
diff --git a/pkix/src/main/jdk1.2/org/spongycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java b/pkix/src/main/jdk1.2/org/spongycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java
new file mode 100644
index 00000000..c3970ee6
--- /dev/null
+++ b/pkix/src/main/jdk1.2/org/spongycastle/cert/crmf/jcajce/JceCRMFEncryptorBuilder.java
@@ -0,0 +1,135 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.ProviderJcaJceHelper;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.2/org/spongycastle/cert/jcajce/JcaAttrCertStore.java b/pkix/src/main/jdk1.2/org/spongycastle/cert/jcajce/JcaAttrCertStore.java
new file mode 100644
index 00000000..3135567b
--- /dev/null
+++ b/pkix/src/main/jdk1.2/org/spongycastle/cert/jcajce/JcaAttrCertStore.java
@@ -0,0 +1,72 @@
+package org.spongycastle.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.spongycastle.util.CollectionStore;
+import org.spongycastle.x509.X509AttributeCertificate;
+
+/**
+ * Class for storing Attribute Certificates for later lookup.
+ * <p>
+ * The class will convert X509AttributeCertificate objects into X509AttributeCertificateHolder objects.
+ * </p>
+ */
+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;
+ }
+}
diff --git a/pkix/src/main/jdk1.2/org/spongycastle/cms/bc/BcCMSContentEncryptorBuilder.java b/pkix/src/main/jdk1.2/org/spongycastle/cms/bc/BcCMSContentEncryptorBuilder.java
new file mode 100644
index 00000000..0e0c1f9f
--- /dev/null
+++ b/pkix/src/main/jdk1.2/org/spongycastle/cms/bc/BcCMSContentEncryptorBuilder.java
@@ -0,0 +1,124 @@
+package org.spongycastle.cms.bc;
+
+import java.io.OutputStream;
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.crypto.BufferedBlockCipher;
+import org.spongycastle.crypto.CipherKeyGenerator;
+import org.spongycastle.crypto.StreamCipher;
+import org.spongycastle.crypto.io.CipherOutputStream;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.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());
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.2/org/spongycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java b/pkix/src/main/jdk1.2/org/spongycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
new file mode 100644
index 00000000..60bd74a7
--- /dev/null
+++ b/pkix/src/main/jdk1.2/org/spongycastle/cms/jcajce/JceCMSContentEncryptorBuilder.java
@@ -0,0 +1,161 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.operator.OutputEncryptor;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.2/org/spongycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java b/pkix/src/main/jdk1.2/org/spongycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java
new file mode 100644
index 00000000..ab168ffb
--- /dev/null
+++ b/pkix/src/main/jdk1.2/org/spongycastle/cms/jcajce/JceCMSMacCalculatorBuilder.java
@@ -0,0 +1,155 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.jcajce.io.MacOutputStream;
+import org.spongycastle.operator.GenericKey;
+import org.spongycastle.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;
+ }
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java
deleted file mode 100644
index 21692926..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package 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.util.DefaultJcaJceHelper;
-import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
-import org.bouncycastle.jcajce.util.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;
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java
deleted file mode 100644
index 3a46f10d..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java
deleted file mode 100644
index 7b9e30ce..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java
deleted file mode 100644
index 6fca1ee7..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaCertStoreBuilder.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX500NameUtil.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX500NameUtil.java
deleted file mode 100644
index 8bffc671..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX500NameUtil.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package 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());
-}
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509ExtensionUtils.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509ExtensionUtils.java
deleted file mode 100644
index 2878f44f..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509ExtensionUtils.java
+++ /dev/null
@@ -1,138 +0,0 @@
-package org.bouncycastle.cert.jcajce;
-
-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.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.x500.X500Name;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
-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.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 java.security.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()));
- }
-
- public AuthorityKeyIdentifier createAuthorityKeyIdentifier(PublicKey pubKey, GeneralNames generalNames, BigInteger serial)
- {
- return super.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), generalNames, serial);
- }
-
- /**
- * Return a RFC 3280 type 1 key identifier. As in:
- * <pre>
- * (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).
- * </pre>
- * @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:
- * <pre>
- * (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.
- * </pre>
- * @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;
- }
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v1CertificateBuilder.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v1CertificateBuilder.java
deleted file mode 100644
index 4102ac53..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v1CertificateBuilder.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v2CRLBuilder.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v2CRLBuilder.java
deleted file mode 100644
index 06d55fe4..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v2CRLBuilder.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java
deleted file mode 100644
index cc293abd..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/JcaX509v3CertificateBuilder.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package 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;
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/ProviderCertHelper.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/ProviderCertHelper.java
deleted file mode 100644
index 7fe875be..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/jcajce/ProviderCertHelper.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package 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());
- }
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java
deleted file mode 100644
index a3666398..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/ocsp/jcajce/JcaRespID.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java
deleted file mode 100644
index 16045313..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaSelectorConverter.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package 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());
-}
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
deleted file mode 100644
index 69834015..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java b/pkix/src/main/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java
deleted file mode 100644
index 648b24fd..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package 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;
- }
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java b/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java
deleted file mode 100644
index 46555b91..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JcaSelectorConverter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package 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());
-}
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JcaSignerId.java b/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JcaSignerId.java
deleted file mode 100644
index 129e85e3..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JcaSignerId.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package 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));
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java
deleted file mode 100644
index d8ece7e5..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JcaX509CertSelectorConverter.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientId.java b/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientId.java
deleted file mode 100644
index 50a95351..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientId.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package 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");
- }
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JceKeyTransRecipientId.java b/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JceKeyTransRecipientId.java
deleted file mode 100644
index e46807b1..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/cms/jcajce/JceKeyTransRecipientId.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package 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(), CMSUtils.getSubjectKeyId(certificate));
- }
-
- private static X509Principal extractIssuer(X509Certificate certificate)
- {
- try
- {
- return PrincipalUtil.getIssuerX509Principal(certificate);
- }
- catch (CertificateEncodingException e)
- {
- throw new IllegalStateException("can't extract issuer");
- }
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/eac/jcajce/ProviderEACHelper.java b/pkix/src/main/jdk1.3/org/bouncycastle/eac/jcajce/ProviderEACHelper.java
deleted file mode 100644
index 84d33522..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/eac/jcajce/ProviderEACHelper.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/eac/operator/jcajce/ProviderEACHelper.java b/pkix/src/main/jdk1.3/org/bouncycastle/eac/operator/jcajce/ProviderEACHelper.java
deleted file mode 100644
index 2c2105a9..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/eac/operator/jcajce/ProviderEACHelper.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package 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());
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java b/pkix/src/main/jdk1.3/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
deleted file mode 100644
index b46a7eb3..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.bouncycastle.operator.jcajce;
-
-
-import java.io.IOException;
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.spec.AlgorithmParameterSpec;
-
-import org.bouncycastle.asn1.ASN1Encodable;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.DEROctetString;
-import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-import org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
-
-public class JcaAlgorithmParametersConverter
-{
- public JcaAlgorithmParametersConverter()
- {
- }
-
- public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algId, AlgorithmParameters parameters)
- throws InvalidAlgorithmParameterException
- {
- try
- {
- ASN1Encodable params = ASN1Primitive.fromByteArray(parameters.getEncoded());
-
- return new AlgorithmIdentifier(algId, params);
- }
- catch (IOException e)
- {
- throw new InvalidAlgorithmParameterException("unable to encode parameters object: " + e.getMessage());
- }
- }
-
- public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algorithm, AlgorithmParameterSpec algorithmSpec)
- throws InvalidAlgorithmParameterException
- {
- throw new InvalidAlgorithmParameterException("unknown parameter spec passed.");
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/operator/jcajce/OperatorHelper.java b/pkix/src/main/jdk1.3/org/bouncycastle/operator/jcajce/OperatorHelper.java
deleted file mode 100644
index 4f229ef5..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/operator/jcajce/OperatorHelper.java
+++ /dev/null
@@ -1,470 +0,0 @@
-package org.bouncycastle.operator.jcajce;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.security.AlgorithmParameters;
-import java.security.GeneralSecurityException;
-import java.security.KeyFactory;
-import java.security.MessageDigest;
-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.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-//import java.security.spec.PSSParameterSpec;
-import java.security.spec.X509EncodedKeySpec;
-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.x509.SubjectPublicKeyInfo;
-import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.jcajce.util.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);
- }
- }
-
- AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)
- throws OperatorCreationException
- {
- AlgorithmParameters parameters;
-
- if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
- {
- return null;
- }
-
- try
- {
- parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
- }
- catch (NoSuchAlgorithmException e)
- {
- return null; // There's a good chance there aren't any!
- }
- catch (NoSuchProviderException e)
- {
- throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
- }
-
- try
- {
- parameters.init(cipherAlgId.getParameters().toASN1Primitive().getEncoded());
- }
- catch (IOException e)
- {
- throw new OperatorCreationException("cannot initialise algorithm parameters: " + e.getMessage(), e);
- }
-
- return parameters;
- }
-
- 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);
-
- JcaJceUtils.loadParameters(params, algorithm.getParameters());
-
- 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);
- }
- }
-
- public PublicKey convertPublicKey(SubjectPublicKeyInfo publicKeyInfo)
- throws OperatorCreationException
- {
- try
- {
- KeyFactory keyFact = helper.createKeyFactory(publicKeyInfo.getAlgorithm().getAlgorithm().getId());
-
- return keyFact.generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
- }
- catch (IOException e)
- {
- throw new OperatorCreationException("cannot get encoded form of key: " + e.getMessage(), e);
- }
- catch (NoSuchAlgorithmException e)
- {
- throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
- }
- catch (NoSuchProviderException e)
- {
- throw new OperatorCreationException("cannot find factory provider: " + e.getMessage(), e);
- }
- catch (InvalidKeySpecException e)
- {
- throw new OperatorCreationException("cannot create key factory: " + 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();
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java b/pkix/src/main/jdk1.3/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java
deleted file mode 100644
index 89687442..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package 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()));
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedData.java b/pkix/src/main/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedData.java
deleted file mode 100644
index e352f021..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedData.java
+++ /dev/null
@@ -1,204 +0,0 @@
-package 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().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 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();
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java b/pkix/src/main/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java
deleted file mode 100644
index 94e8079e..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedDataParser.java
+++ /dev/null
@@ -1,207 +0,0 @@
-package 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);
- }
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java b/pkix/src/main/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java
deleted file mode 100644
index 2289583e..00000000
--- a/pkix/src/main/jdk1.3/org/bouncycastle/tsp/cms/CMSTimeStampedGenerator.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package 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);
- }
-}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java
new file mode 100644
index 00000000..eac007e0
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessage.java
@@ -0,0 +1,55 @@
+package org.spongycastle.cert.crmf.jcajce;
+
+import java.security.Provider;
+import java.security.PublicKey;
+
+import org.spongycastle.asn1.crmf.CertReqMsg;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.crmf.CRMFException;
+import org.spongycastle.cert.crmf.CertificateRequestMessage;
+import org.spongycastle.jcajce.util.DefaultJcaJceHelper;
+import org.spongycastle.jcajce.util.NamedJcaJceHelper;
+import org.spongycastle.jcajce.util.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;
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java
new file mode 100644
index 00000000..6b2f8521
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaCertificateRequestMessageBuilder.java
@@ -0,0 +1,25 @@
+package org.spongycastle.cert.crmf.jcajce;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java
new file mode 100644
index 00000000..9e2963c8
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/crmf/jcajce/JcaPKIArchiveControlBuilder.java
@@ -0,0 +1,22 @@
+package org.spongycastle.cert.crmf.jcajce;
+
+import java.security.PrivateKey;
+
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java
new file mode 100644
index 00000000..37a1723c
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaCertStoreBuilder.java
@@ -0,0 +1,151 @@
+package org.spongycastle.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.spongycastle.jce.cert.CertStore;
+import java.security.cert.CertificateException;
+import org.spongycastle.jce.cert.CollectionCertStoreParameters;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.spongycastle.cert.X509CRLHolder;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX500NameUtil.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX500NameUtil.java
new file mode 100644
index 00000000..840dde55
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX500NameUtil.java
@@ -0,0 +1,58 @@
+package org.spongycastle.cert.jcajce;
+
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x500.X500NameStyle;
+import org.spongycastle.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());
+}
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java
new file mode 100644
index 00000000..f40ab480
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509ExtensionUtils.java
@@ -0,0 +1,138 @@
+package org.spongycastle.cert.jcajce;
+
+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.PublicKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.X509ExtensionUtils;
+import org.spongycastle.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 java.security.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()));
+ }
+
+ public AuthorityKeyIdentifier createAuthorityKeyIdentifier(PublicKey pubKey, GeneralNames generalNames, BigInteger serial)
+ {
+ return super.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), generalNames, serial);
+ }
+
+ /**
+ * Return a RFC 3280 type 1 key identifier. As in:
+ * <pre>
+ * (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).
+ * </pre>
+ * @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:
+ * <pre>
+ * (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.
+ * </pre>
+ * @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;
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java
new file mode 100644
index 00000000..b67959bc
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v1CertificateBuilder.java
@@ -0,0 +1,31 @@
+package org.spongycastle.cert.jcajce;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.util.Date;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java
new file mode 100644
index 00000000..4b1f4907
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v2CRLBuilder.java
@@ -0,0 +1,15 @@
+package org.spongycastle.cert.jcajce;
+
+import java.util.Date;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cert.X509v2CRLBuilder;
+
+public class JcaX509v2CRLBuilder
+ extends X509v2CRLBuilder
+{
+ public JcaX509v2CRLBuilder(X500Name issuer, Date now)
+ {
+ super(issuer, now);
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java
new file mode 100644
index 00000000..4f7a4a1e
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/JcaX509v3CertificateBuilder.java
@@ -0,0 +1,54 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.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;
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/ProviderCertHelper.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/ProviderCertHelper.java
new file mode 100644
index 00000000..a28a7c56
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/jcajce/ProviderCertHelper.java
@@ -0,0 +1,30 @@
+package org.spongycastle.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());
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java
new file mode 100644
index 00000000..41d9072c
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/ocsp/jcajce/JcaRespID.java
@@ -0,0 +1,19 @@
+package org.spongycastle.cert.ocsp.jcajce;
+
+import java.security.PublicKey;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cert.ocsp.OCSPException;
+import org.spongycastle.cert.ocsp.RespID;
+import org.spongycastle.operator.DigestCalculator;
+
+public class JcaRespID
+ extends RespID
+{
+ public JcaRespID(PublicKey pubKey, DigestCalculator digCalc)
+ throws OCSPException
+ {
+ super(SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()), digCalc);
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java
new file mode 100644
index 00000000..cede4acc
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaSelectorConverter.java
@@ -0,0 +1,34 @@
+package org.spongycastle.cert.selector.jcajce;
+
+import org.spongycastle.jce.cert.X509CertSelector;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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());
+}
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
new file mode 100644
index 00000000..b2dbb563
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertSelectorConverter.java
@@ -0,0 +1,57 @@
+package org.spongycastle.cert.selector.jcajce;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import org.spongycastle.jce.cert.X509CertSelector;
+
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java
new file mode 100644
index 00000000..3280af2a
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cert/selector/jcajce/JcaX509CertificateHolderSelector.java
@@ -0,0 +1,57 @@
+package org.spongycastle.cert.selector.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.jce.X509Principal;
+import org.spongycastle.jce.PrincipalUtil;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.X509Extension;
+import org.spongycastle.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;
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSelectorConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSelectorConverter.java
new file mode 100644
index 00000000..c6d0cebe
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSelectorConverter.java
@@ -0,0 +1,54 @@
+package org.spongycastle.cms.jcajce;
+
+import org.spongycastle.jce.cert.X509CertSelector;
+
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cms.KeyTransRecipientId;
+import org.spongycastle.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());
+}
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSignerId.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSignerId.java
new file mode 100644
index 00000000..99650cfb
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaSignerId.java
@@ -0,0 +1,36 @@
+package org.spongycastle.cms.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cms.SignerId;
+import org.spongycastle.jce.PrincipalUtil;
+import org.spongycastle.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));
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java
new file mode 100644
index 00000000..594ed1d5
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JcaX509CertSelectorConverter.java
@@ -0,0 +1,24 @@
+package org.spongycastle.cms.jcajce;
+
+import org.spongycastle.jce.cert.X509CertSelector;
+
+import org.spongycastle.cms.KeyTransRecipientId;
+import org.spongycastle.cms.SignerId;
+
+public class JcaX509CertSelectorConverter
+ extends org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java
new file mode 100644
index 00000000..91875037
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientId.java
@@ -0,0 +1,32 @@
+package org.spongycastle.cms.jcajce;
+
+import java.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.jce.PrincipalUtil;
+import org.spongycastle.jce.X509Principal;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.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");
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java
new file mode 100644
index 00000000..5bac48b5
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/cms/jcajce/JceKeyTransRecipientId.java
@@ -0,0 +1,30 @@
+package org.spongycastle.cms.jcajce;
+
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.cms.KeyTransRecipientId;
+import org.spongycastle.jce.PrincipalUtil;
+import org.spongycastle.jce.X509Principal;
+
+public class JceKeyTransRecipientId
+ extends KeyTransRecipientId
+{
+ public JceKeyTransRecipientId(X509Certificate certificate)
+ {
+ super(X500Name.getInstance(extractIssuer(certificate)), certificate.getSerialNumber(), CMSUtils.getSubjectKeyId(certificate));
+ }
+
+ private static X509Principal extractIssuer(X509Certificate certificate)
+ {
+ try
+ {
+ return PrincipalUtil.getIssuerX509Principal(certificate);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IllegalStateException("can't extract issuer");
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/eac/jcajce/ProviderEACHelper.java b/pkix/src/main/jdk1.3/org/spongycastle/eac/jcajce/ProviderEACHelper.java
new file mode 100644
index 00000000..4bc4dfa3
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/eac/jcajce/ProviderEACHelper.java
@@ -0,0 +1,23 @@
+package org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java b/pkix/src/main/jdk1.3/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java
new file mode 100644
index 00000000..dcdd1e1c
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/eac/operator/jcajce/ProviderEACHelper.java
@@ -0,0 +1,23 @@
+package org.spongycastle.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());
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java b/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
new file mode 100644
index 00000000..a4de4911
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
@@ -0,0 +1,44 @@
+package org.spongycastle.operator.jcajce;
+
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RSAESOAEPparams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+
+public class JcaAlgorithmParametersConverter
+{
+ public JcaAlgorithmParametersConverter()
+ {
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algId, AlgorithmParameters parameters)
+ throws InvalidAlgorithmParameterException
+ {
+ try
+ {
+ ASN1Encodable params = ASN1Primitive.fromByteArray(parameters.getEncoded());
+
+ return new AlgorithmIdentifier(algId, params);
+ }
+ catch (IOException e)
+ {
+ throw new InvalidAlgorithmParameterException("unable to encode parameters object: " + e.getMessage());
+ }
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algorithm, AlgorithmParameterSpec algorithmSpec)
+ throws InvalidAlgorithmParameterException
+ {
+ throw new InvalidAlgorithmParameterException("unknown parameter spec passed.");
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/OperatorHelper.java b/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/OperatorHelper.java
new file mode 100644
index 00000000..419f0939
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/operator/jcajce/OperatorHelper.java
@@ -0,0 +1,470 @@
+package org.spongycastle.operator.jcajce;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+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.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+//import java.security.spec.PSSParameterSpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.DERNull;
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RSASSAPSSparams;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.jcajce.util.JcaJceHelper;
+import org.spongycastle.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);
+ }
+ }
+
+ AlgorithmParameters createAlgorithmParameters(AlgorithmIdentifier cipherAlgId)
+ throws OperatorCreationException
+ {
+ AlgorithmParameters parameters;
+
+ if (cipherAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption))
+ {
+ return null;
+ }
+
+ try
+ {
+ parameters = helper.createAlgorithmParameters(cipherAlgId.getAlgorithm().getId());
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ return null; // There's a good chance there aren't any!
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot create algorithm parameters: " + e.getMessage(), e);
+ }
+
+ try
+ {
+ parameters.init(cipherAlgId.getParameters().toASN1Primitive().getEncoded());
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("cannot initialise algorithm parameters: " + e.getMessage(), e);
+ }
+
+ return parameters;
+ }
+
+ 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);
+
+ JcaJceUtils.loadParameters(params, algorithm.getParameters());
+
+ 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);
+ }
+ }
+
+ public PublicKey convertPublicKey(SubjectPublicKeyInfo publicKeyInfo)
+ throws OperatorCreationException
+ {
+ try
+ {
+ KeyFactory keyFact = helper.createKeyFactory(publicKeyInfo.getAlgorithm().getAlgorithm().getId());
+
+ return keyFact.generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded()));
+ }
+ catch (IOException e)
+ {
+ throw new OperatorCreationException("cannot get encoded form of key: " + e.getMessage(), e);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new OperatorCreationException("cannot create key factory: " + e.getMessage(), e);
+ }
+ catch (NoSuchProviderException e)
+ {
+ throw new OperatorCreationException("cannot find factory provider: " + e.getMessage(), e);
+ }
+ catch (InvalidKeySpecException e)
+ {
+ throw new OperatorCreationException("cannot create key factory: " + 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();
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java b/pkix/src/main/jdk1.3/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java
new file mode 100644
index 00000000..2e0000e0
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/pkcs/jcajce/JcaPKCS10CertificationRequestBuilder.java
@@ -0,0 +1,25 @@
+package org.spongycastle.pkcs.jcajce;
+
+import java.security.PublicKey;
+
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.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()));
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedData.java b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedData.java
new file mode 100644
index 00000000..0b5cb6fd
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedData.java
@@ -0,0 +1,204 @@
+package org.spongycastle.tsp.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfo;
+import org.spongycastle.asn1.cms.Evidence;
+import org.spongycastle.asn1.cms.TimeStampAndCRL;
+import org.spongycastle.asn1.cms.TimeStampTokenEvidence;
+import org.spongycastle.asn1.cms.TimeStampedData;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.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 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();
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java
new file mode 100644
index 00000000..2b1a695f
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedDataParser.java
@@ -0,0 +1,207 @@
+package org.spongycastle.tsp.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.spongycastle.asn1.BERTags;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.cms.CMSObjectIdentifiers;
+import org.spongycastle.asn1.cms.ContentInfoParser;
+import org.spongycastle.asn1.cms.TimeStampedDataParser;
+import org.spongycastle.cms.CMSContentInfoParser;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.OperatorCreationException;
+import org.spongycastle.tsp.TimeStampToken;
+import org.spongycastle.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);
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java
new file mode 100644
index 00000000..614a744b
--- /dev/null
+++ b/pkix/src/main/jdk1.3/org/spongycastle/tsp/cms/CMSTimeStampedGenerator.java
@@ -0,0 +1,90 @@
+package org.spongycastle.tsp.cms;
+
+import java.net.URL;
+
+import org.spongycastle.asn1.ASN1Boolean;
+import org.spongycastle.asn1.DERBoolean;
+import org.spongycastle.asn1.DERIA5String;
+import org.spongycastle.asn1.DERUTF8String;
+import org.spongycastle.asn1.cms.Attributes;
+import org.spongycastle.asn1.cms.MetaData;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.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);
+ }
+}
diff --git a/pkix/src/main/jdk1.4/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java b/pkix/src/main/jdk1.4/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java
deleted file mode 100644
index 3b3dee78..00000000
--- a/pkix/src/main/jdk1.4/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java
+++ /dev/null
@@ -1,215 +0,0 @@
-package 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);
- }
- }
- }
- }
-}
diff --git a/pkix/src/main/jdk1.4/org/bouncycastle/eac/jcajce/JcaPublicKeyConverter.java b/pkix/src/main/jdk1.4/org/bouncycastle/eac/jcajce/JcaPublicKeyConverter.java
deleted file mode 100644
index 33e518ef..00000000
--- a/pkix/src/main/jdk1.4/org/bouncycastle/eac/jcajce/JcaPublicKeyConverter.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package 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());
- }
- }
-}
diff --git a/pkix/src/main/jdk1.4/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java b/pkix/src/main/jdk1.4/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
deleted file mode 100644
index b46a7eb3..00000000
--- a/pkix/src/main/jdk1.4/org/bouncycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.bouncycastle.operator.jcajce;
-
-
-import java.io.IOException;
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.spec.AlgorithmParameterSpec;
-
-import org.bouncycastle.asn1.ASN1Encodable;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.DEROctetString;
-import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-import org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
-
-public class JcaAlgorithmParametersConverter
-{
- public JcaAlgorithmParametersConverter()
- {
- }
-
- public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algId, AlgorithmParameters parameters)
- throws InvalidAlgorithmParameterException
- {
- try
- {
- ASN1Encodable params = ASN1Primitive.fromByteArray(parameters.getEncoded());
-
- return new AlgorithmIdentifier(algId, params);
- }
- catch (IOException e)
- {
- throw new InvalidAlgorithmParameterException("unable to encode parameters object: " + e.getMessage());
- }
- }
-
- public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algorithm, AlgorithmParameterSpec algorithmSpec)
- throws InvalidAlgorithmParameterException
- {
- throw new InvalidAlgorithmParameterException("unknown parameter spec passed.");
- }
-}
diff --git a/pkix/src/main/jdk1.4/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java b/pkix/src/main/jdk1.4/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java
new file mode 100644
index 00000000..d808d507
--- /dev/null
+++ b/pkix/src/main/jdk1.4/org/spongycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java
@@ -0,0 +1,215 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1EncodableVector;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1OctetString;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.DERSequence;
+import org.spongycastle.asn1.cms.KeyAgreeRecipientIdentifier;
+import org.spongycastle.asn1.cms.RecipientEncryptedKey;
+import org.spongycastle.asn1.cms.RecipientKeyIdentifier;
+import org.spongycastle.asn1.cms.ecc.MQVuserKeyingMaterial;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.cms.CMSAlgorithm;
+import org.spongycastle.cms.CMSEnvelopedGenerator;
+import org.spongycastle.cms.CMSException;
+import org.spongycastle.cms.KeyAgreeRecipientInfoGenerator;
+import org.spongycastle.jce.interfaces.ECPublicKey;
+import org.spongycastle.jce.spec.ECParameterSpec;
+import org.spongycastle.jce.spec.MQVPrivateKeySpec;
+import org.spongycastle.jce.spec.MQVPublicKeySpec;
+import org.spongycastle.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);
+ }
+ }
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.4/org/spongycastle/eac/jcajce/JcaPublicKeyConverter.java b/pkix/src/main/jdk1.4/org/spongycastle/eac/jcajce/JcaPublicKeyConverter.java
new file mode 100644
index 00000000..9c1801ec
--- /dev/null
+++ b/pkix/src/main/jdk1.4/org/spongycastle/eac/jcajce/JcaPublicKeyConverter.java
@@ -0,0 +1,141 @@
+package org.spongycastle.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.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.eac.EACObjectIdentifiers;
+import org.spongycastle.asn1.eac.ECDSAPublicKey;
+import org.spongycastle.asn1.eac.PublicKeyDataObject;
+import org.spongycastle.asn1.eac.RSAPublicKey;
+import org.spongycastle.eac.EACException;
+import org.spongycastle.jce.interfaces.ECPublicKey;
+import org.spongycastle.jce.spec.ECParameterSpec;
+import org.spongycastle.jce.spec.ECPublicKeySpec;
+import org.spongycastle.math.ec.ECCurve;
+import org.spongycastle.math.ec.ECFieldElement;
+import org.spongycastle.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());
+ }
+ }
+}
diff --git a/pkix/src/main/jdk1.4/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java b/pkix/src/main/jdk1.4/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
new file mode 100644
index 00000000..a4de4911
--- /dev/null
+++ b/pkix/src/main/jdk1.4/org/spongycastle/operator/jcajce/JcaAlgorithmParametersConverter.java
@@ -0,0 +1,44 @@
+package org.spongycastle.operator.jcajce;
+
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.spongycastle.asn1.ASN1Encodable;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.DEROctetString;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.RSAESOAEPparams;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
+
+public class JcaAlgorithmParametersConverter
+{
+ public JcaAlgorithmParametersConverter()
+ {
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algId, AlgorithmParameters parameters)
+ throws InvalidAlgorithmParameterException
+ {
+ try
+ {
+ ASN1Encodable params = ASN1Primitive.fromByteArray(parameters.getEncoded());
+
+ return new AlgorithmIdentifier(algId, params);
+ }
+ catch (IOException e)
+ {
+ throw new InvalidAlgorithmParameterException("unable to encode parameters object: " + e.getMessage());
+ }
+ }
+
+ public AlgorithmIdentifier getAlgorithmIdentifier(ASN1ObjectIdentifier algorithm, AlgorithmParameterSpec algorithmSpec)
+ throws InvalidAlgorithmParameterException
+ {
+ throw new InvalidAlgorithmParameterException("unknown parameter spec passed.");
+ }
+}