/*
* JBoss, Home of Professional Open Source.
* Copyright 2012, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.test.capedwarf.appidentity.test;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collection;
import com.google.appengine.api.appidentity.AppIdentityService;
import com.google.appengine.api.appidentity.AppIdentityServiceFactory;
import com.google.appengine.api.appidentity.PublicCertificate;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.capedwarf.common.io.Base64Utils;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.test.capedwarf.common.support.JBoss;
import org.jboss.test.capedwarf.common.test.TestBase;
import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
/**
* @author Marko Luksa
*/
@RunWith(Arquillian.class)
@Category(JBoss.class)
public class AppIdentityTest extends TestBase {
@Deployment
public static Archive getDeployment() {
final WebArchive war = getCapedwarfDeployment();
war.addAsWebInfResource("jboss-deployment-structure.xml");
return war;
}
@Test
public void test() {
AppIdentityService service = AppIdentityServiceFactory.getAppIdentityService();
AppIdentityService.SigningResult signingResult = service.signForApp("CapeDwarf".getBytes());
byte[] signature = signingResult.getSignature();
Assert.assertTrue(isSignedByAny(signature, service.getPublicCertificatesForApp()));
}
private boolean isSignedByAny(byte[] signature, Collection<PublicCertificate> certificates) {
for (PublicCertificate certificate : certificates) {
if (isSignedBy(signature, certificate)) {
return true;
}
}
return false;
}
private boolean isSignedBy(byte[] signature, PublicCertificate certificate) {
try {
PemReader pemReader = new PemReader(new StringReader(certificate.getX509CertificateInPemFormat()));
byte[] content = pemReader.readPemObject();
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(content));
Signature verifier = Signature.getInstance("SHA256withRSA");
verifier.initVerify(cert);
verifier.update("CapeDwarf".getBytes());
return verifier.verify(signature);
} catch (Exception e) {
throw new RuntimeException("Cannot verify signature", e);
}
}
// Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
private static class PemReader extends BufferedReader {
private static final String BEGIN = "-----BEGIN ";
private static final String END = "-----END ";
private PemReader(Reader reader) {
super(reader);
}
private byte[] readPemObject() throws Exception {
String line = readLine();
while (line != null && line.startsWith(BEGIN) == false) {
line = readLine();
}
if (line != null) {
line = line.substring(BEGIN.length());
int index = line.indexOf('-');
String type = line.substring(0, index);
if (index > 0) {
String endMarker = END + type;
StringBuilder buf = new StringBuilder();
while ((line = readLine()) != null) {
if (line.contains(":")) {
continue;
}
if (line.contains(endMarker)) {
break;
}
buf.append(line.trim());
}
if (line == null) {
throw new IOException(endMarker + " not found");
}
return Base64Utils.decode(buf.toString());
}
}
return null;
}
}
}