blob: 63e1fe74074fc8cf5e893ddacae3ed24254b1be0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.pgp.util;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
import org.bouncycastle.openpgp.PGPOnePassSignature;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
/**
* Pretty Good Privacy Operation Utilities
*/
public class PGPOperationUtils {
private static final boolean NESTED_SIGNATURE_DISABLED = false;
private static final int BUFFER_SIZE = 2048;
private static final long MODIFIED_MILLISECONDS = 86400000;
private static final Date MODIFIED = new Date(MODIFIED_MILLISECONDS);
private static final String FILE_NAME = String.class.getSimpleName();
private static final char FILE_TYPE = PGPLiteralDataGenerator.BINARY;
/**
* Get data signed using one-pass signature generator
*
* @param contents Byte array contents to be signed
* @param privateKey Private Key used for signing
* @return Signed byte array
* @throws PGPException Thrown when signature initialization failed
* @throws IOException Thrown when signature generation failed
*/
public static byte[] getOnePassSignedData(final byte[] contents, final PGPPrivateKey privateKey) throws IOException, PGPException {
final PGPSignatureGenerator signatureGenerator = getSignatureGenerator(privateKey);
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final PGPOnePassSignature onePassSignature = signatureGenerator.generateOnePassVersion(NESTED_SIGNATURE_DISABLED);
onePassSignature.encode(outputStream);
outputStream.write(contents);
signatureGenerator.update(contents);
final PGPSignature signature = signatureGenerator.generate();
signature.encode(outputStream);
return outputStream.toByteArray();
}
/**
* Get data signed using one-pass signature generator wrapping literal data
*
* @param contents Byte array contents to be signed
* @param privateKey Private Key used for signing
* @return Signed byte array
* @throws PGPException Thrown when signature initialization failed
* @throws IOException Thrown when signature generation failed
*/
public static byte[] getOnePassSignedLiteralData(final byte[] contents, final PGPPrivateKey privateKey) throws IOException, PGPException {
final PGPSignatureGenerator signatureGenerator = getSignatureGenerator(privateKey);
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final PGPOnePassSignature onePassSignature = signatureGenerator.generateOnePassVersion(NESTED_SIGNATURE_DISABLED);
onePassSignature.encode(outputStream);
final PGPLiteralDataGenerator generator = new PGPLiteralDataGenerator();
final byte[] buffer = new byte[BUFFER_SIZE];
try (final OutputStream literalStream = generator.open(outputStream, FILE_TYPE, FILE_NAME, MODIFIED, buffer)) {
literalStream.write(contents);
signatureGenerator.update(contents);
}
final PGPSignature signature = signatureGenerator.generate();
signature.encode(outputStream);
return outputStream.toByteArray();
}
private static PGPSignatureGenerator getSignatureGenerator(final PGPPrivateKey privateKey) throws PGPException {
final PGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(privateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512);
final PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder);
signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey);
return signatureGenerator;
}
}