Java tutorial
/** * diqube: Distributed Query Base. * * Copyright (C) 2015 Bastian Gloeckle * * This file is part of diqube. * * diqube is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.diqube.ticket; import java.nio.ByteBuffer; import javax.inject.Inject; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; import org.bouncycastle.crypto.signers.RSADigestSigner; import org.diqube.context.AutoInstatiate; import org.diqube.thrift.base.thrift.Ticket; import org.diqube.util.Pair; /** * Service that can sign {@link Ticket}s and verify integrity on those that have been signed already. * * @author Bastian Gloeckle */ @AutoInstatiate public class TicketSignatureService { @Inject private TicketRsaKeyManager keyManager; /** * Checks if a {@link Ticket} has a valid signature. * * @param deserializedTicket * The result of {@link TicketUtil#deserialize(ByteBuffer)} of the serialized {@link Ticket}. * @return true if {@link Ticket} signature is valid. */ public boolean isValidTicketSignature(Pair<Ticket, byte[]> deserializedTicket) { for (RSAKeyParameters pubKey : keyManager.getPublicValidationKeys()) { RSADigestSigner signer = new RSADigestSigner(new SHA256Digest()); signer.init(false, pubKey); signer.update(deserializedTicket.getRight(), 0, deserializedTicket.getRight().length); if (signer.verifySignature(deserializedTicket.getLeft().getSignature())) return true; } return false; } /** * Calculates the signature of a ticket and updates the given {@link Ticket} object directly. * * @throws IllegalStateException * If ticket cannot be signed. */ public void signTicket(Ticket ticket) throws IllegalStateException { byte[] serialized = TicketUtil.serialize(ticket); byte[] claimBytes = TicketUtil.deserialize(ByteBuffer.wrap(serialized)).getRight(); RSAPrivateCrtKeyParameters signingKey = keyManager.getPrivateSigningKey(); if (signingKey == null) throw new IllegalStateException( "Cannot sign ticket because there is no private signing key available."); RSADigestSigner signer = new RSADigestSigner(new SHA256Digest()); signer.init(true, signingKey); signer.update(claimBytes, 0, claimBytes.length); try { byte[] signature = signer.generateSignature(); ticket.setSignature(signature); } catch (DataLengthException | CryptoException e) { throw new IllegalStateException("Cannot sign ticket", e); } } }