/* * 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.ivy.plugins.signer.bouncycastle; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import java.security.SignatureException; import java.util.Iterator; import org.apache.ivy.plugins.signer.SignatureGenerator; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPUtil; public class OpenPGPSignatureGenerator implements SignatureGenerator { private static final long MASK = 0xFFFFFFFFL; static { Security.addProvider(new BouncyCastleProvider()); } private String name; private String secring; private String password; private String keyId; private PGPSecretKey pgpSec; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getExtension() { return "asc"; } public void setPassword(String password) { this.password = password; } public void setSecring(String secring) { this.secring = secring; } public void setKeyId(String keyId) { if (!"auto".equals(keyId)) { this.keyId = keyId; } } public void sign(File src, File dest) throws IOException { OutputStream out = null; InputStream in = null; InputStream keyIn = null; try { if (secring == null) { secring = System.getProperty("user.home") + "/.gnupg/secring.gpg"; } if (pgpSec == null) { keyIn = new FileInputStream(secring); pgpSec = readSecretKey(keyIn); } PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(password.toCharArray(), BouncyCastleProvider.PROVIDER_NAME); PGPSignatureGenerator sGen = new PGPSignatureGenerator(pgpSec.getPublicKey() .getAlgorithm(), PGPUtil.SHA1, BouncyCastleProvider.PROVIDER_NAME); sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); in = new FileInputStream(src); out = new BCPGOutputStream(new ArmoredOutputStream(new FileOutputStream(dest))); int ch = 0; while ((ch = in.read()) >= 0) { sGen.update((byte) ch); } sGen.generate().encode(out); } catch (SignatureException e) { IOException ioexc = new IOException(); ioexc.initCause(e); throw ioexc; } catch (PGPException e) { IOException ioexc = new IOException(); ioexc.initCause(e); throw ioexc; } catch (NoSuchAlgorithmException e) { IOException ioexc = new IOException(); ioexc.initCause(e); throw ioexc; } catch (NoSuchProviderException e) { IOException ioexc = new IOException(); ioexc.initCause(e); throw ioexc; } finally { if (out != null) { try { out.close(); } catch (IOException e) { } } if (in != null) { try { in.close(); } catch (IOException e) { } } if (keyIn != null) { try { keyIn.close(); } catch (IOException e) { } } } } private PGPSecretKey readSecretKey(InputStream in) throws IOException, PGPException { in = PGPUtil.getDecoderStream(in); PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(in); PGPSecretKey key = null; for (Iterator it = pgpSec.getKeyRings(); key == null && it.hasNext();) { PGPSecretKeyRing kRing = (PGPSecretKeyRing) it.next(); for (Iterator it2 = kRing.getSecretKeys(); key == null && it2.hasNext();) { PGPSecretKey k = (PGPSecretKey) it2.next(); if ((keyId == null) && k.isSigningKey()) { key = k; } if ((keyId != null) && (Long.valueOf(keyId, 16).longValue() == (k.getKeyID() & MASK))) { key = k; } } } if (key == null) { throw new IllegalArgumentException("Can't find encryption key" + (keyId != null ? " '" + keyId + "' " : " ") + "in key ring."); } return key; } }