use of com.github.zhenwei.core.util.io.TeeOutputStream in project LinLong-Java by zhenwei1108.
the class SignerInformation method doVerify.
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
verifyContentTypeAttributeValue();
AttributeTable signedAttrTable = this.getSignedAttributes();
// RFC 6211 Validate Algorithm Identifier protection attribute if present
verifyAlgorithmIdentifierProtectionAttribute(signedAttrTable);
// RFC 3852 11.2 Check the message-digest attribute is correct
verifyMessageDigestAttribute();
// RFC 3852 11.4 Validate countersignature attribute(s)
verifyCounterSignatureAttribute(signedAttrTable);
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);
}
}
use of com.github.zhenwei.core.util.io.TeeOutputStream in project LinLong-Java by zhenwei1108.
the class CMSAuthenticatedDataGenerator method generate.
/**
* 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 = Collections.unmodifiableMap(getBaseParameters(typedData.getContentType(), digestCalculator.getAlgorithmIdentifier(), macCalculator.getAlgorithmIdentifier(), digestCalculator.getDigest()));
if (authGen == null) {
authGen = new DefaultAuthenticatedAttributeTableGenerator();
}
ASN1Set authed = new DERSet(authGen.getAttributes(parameters).toASN1EncodableVector());
try {
OutputStream mOut = macCalculator.getOutputStream();
mOut.write(authed.getEncoded(ASN1Encoding.DER));
mOut.close();
macResult = new DEROctetString(macCalculator.getMac());
} catch (IOException e) {
throw new CMSException("unable to perform MAC calculation: " + e.getMessage(), e);
}
ASN1Set unauthed = (unauthGen != null) ? new BERSet(unauthGen.getAttributes(parameters).toASN1EncodableVector()) : null;
ContentInfo eci = new ContentInfo(typedData.getContentType(), 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("unable to perform MAC calculation: " + e.getMessage(), e);
}
ASN1Set unauthed = (unauthGen != null) ? new BERSet(unauthGen.getAttributes(Collections.EMPTY_MAP).toASN1EncodableVector()) : null;
ContentInfo eci = new ContentInfo(typedData.getContentType(), 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;
}
});
}
use of com.github.zhenwei.core.util.io.TeeOutputStream in project LinLong-Java by zhenwei1108.
the class JcaContentSignerBuilder method buildComposite.
private ContentSigner buildComposite(CompositePrivateKey privateKey) throws OperatorCreationException {
try {
List<PrivateKey> privateKeys = privateKey.getPrivateKeys();
final ASN1Sequence sigAlgIds = ASN1Sequence.getInstance(sigAlgId.getParameters());
final Signature[] sigs = new Signature[sigAlgIds.size()];
for (int i = 0; i != sigAlgIds.size(); i++) {
sigs[i] = helper.createSignature(AlgorithmIdentifier.getInstance(sigAlgIds.getObjectAt(i)));
if (random != null) {
sigs[i].initSign(privateKeys.get(i), random);
} else {
sigs[i].initSign(privateKeys.get(i));
}
}
OutputStream sStream = OutputStreamFactory.createStream(sigs[0]);
for (int i = 1; i != sigs.length; i++) {
sStream = new TeeOutputStream(sStream, OutputStreamFactory.createStream(sigs[i]));
}
final OutputStream sigStream = sStream;
return new ContentSigner() {
OutputStream stream = sigStream;
public AlgorithmIdentifier getAlgorithmIdentifier() {
return sigAlgId;
}
public OutputStream getOutputStream() {
return stream;
}
public byte[] getSignature() {
try {
ASN1EncodableVector sigV = new ASN1EncodableVector();
for (int i = 0; i != sigs.length; i++) {
sigV.add(new DERBitString(sigs[i].sign()));
}
return new DERSequence(sigV).getEncoded(ASN1Encoding.DER);
} catch (IOException e) {
throw new RuntimeOperatorException("exception encoding signature: " + e.getMessage(), e);
} catch (SignatureException e) {
throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e);
}
}
};
} catch (GeneralSecurityException e) {
throw new OperatorCreationException("cannot create signer: " + e.getMessage(), e);
}
}
use of com.github.zhenwei.core.util.io.TeeOutputStream in project LinLong-Java by zhenwei1108.
the class CMSAuthenticatedDataStreamGenerator method open.
/**
* 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, true, 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);
}
}
use of com.github.zhenwei.core.util.io.TeeOutputStream in project LinLong-Java by zhenwei1108.
the class BcKeyStoreSpi method engineStore.
public void engineStore(OutputStream stream, char[] password) throws IOException {
DataOutputStream dOut = new DataOutputStream(stream);
byte[] salt = new byte[STORE_SALT_SIZE];
int iterationCount = MIN_ITERATIONS + (random.nextInt() & 0x3ff);
random.nextBytes(salt);
dOut.writeInt(version);
dOut.writeInt(salt.length);
dOut.write(salt);
dOut.writeInt(iterationCount);
HMac hMac = new HMac(new SHA1Digest());
MacOutputStream mOut = new MacOutputStream(hMac);
PBEParametersGenerator pbeGen = new PKCS12ParametersGenerator(new SHA1Digest());
byte[] passKey = PBEParametersGenerator.PKCS12PasswordToBytes(password);
pbeGen.init(passKey, salt, iterationCount);
if (version < 2) {
hMac.init(pbeGen.generateDerivedMacParameters(hMac.getMacSize()));
} else {
hMac.init(pbeGen.generateDerivedMacParameters(hMac.getMacSize() * 8));
}
for (int i = 0; i != passKey.length; i++) {
passKey[i] = 0;
}
saveStore(new TeeOutputStream(dOut, mOut));
byte[] mac = new byte[hMac.getMacSize()];
hMac.doFinal(mac, 0);
dOut.write(mac);
dOut.close();
}
Aggregations