Package org.keyczar

Source Code of org.keyczar.PkcsImportTest

/*
* Copyright 2011 Google Inc.
*
* Licensed 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.keyczar;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import javax.crypto.BadPaddingException;

import junit.framework.TestCase;

import org.keyczar.enums.KeyPurpose;
import org.keyczar.enums.RsaPadding;
import org.keyczar.exceptions.KeyczarException;
import org.keyczar.util.Base64Coder;

/**
* Tests PkcsKeyReader.
*
* @author swillden@google.com (Shawn Willden)
*/
public class PkcsImportTest extends TestCase {
  private static final String TEST_DATA = "./testdata/certificates/";
  private static final String[] FILE_FORMATS = { "pem", "der" };
  private static final String[] KEY_TYPES = { "rsa", "dsa" };
  private static final String INPUT = "This is some test data";

  /**
   * Tests importing decryption keys in PEM and DER formats.  Verifies that the imported
   * private key can successfully decrypt a message encrypted with the corresponding
   * Keyczar-format public key.  Also verifies that a corrupted message fails to decrypt.
   */
  public void testCryptImport() throws Exception {
    for (String format : FILE_FORMATS)  {
      doTestCryptImport(getPkcs8KeyStream("rsa", format, "crypt"));
    }
  }

  /**
   * Tests importing RSA and DSA signing keys in PEM and DER formats.  Verifies that the
   * imported private signing key generates a signature that can be verified with the
   * corresponding Keycar-format public key.  Also verifies that a corrupted signature
   * or a corrupted message fail to verify.
   */
  public void testSignImport() throws Exception {
    for (String keyType : KEY_TYPES) {
      for (String format : FILE_FORMATS) {
        doTestSignImport(keyType, getPkcs8KeyStream(keyType, format, "sign"));
      }
    }
  }

  /**
   * Verifies that trying to import a DSA key with an RSA padding specifier fails with the
   * correct exception.
   */
  public void testImportDsaWithPadding() throws Exception {
    PkcsKeyReader reader =
        new PkcsKeyReader(KeyPurpose.SIGN_AND_VERIFY, getPkcs8KeyStream("dsa", "der", "sign"),
            RsaPadding.OAEP, "pass");
    try {
      reader.getKey();
      fail("Should throw");
    } catch (KeyczarException e) {
      assertTrue(e.getMessage().contains(RsaPadding.OAEP.name()));
    }
  }

  /**
   * Verifies that trying to import corrupted PKCS#8 keys fails with the correct exception.
   */
  public void testCryptImportCorrupted() throws Exception {
    for (String format : FILE_FORMATS)  {
      try {
        doTestCryptImport(new CorruptedStream(getPkcs8KeyStream("rsa", format, "crypt")));
      } catch (KeyczarException e) {
        assertTrue(e.getMessage().contains("PKCS"));
      }
    }
  }

  private void doTestCryptImport(InputStream pkcs8KeyStream) throws Exception {
    final String ciphertext = new Encrypter(TEST_DATA + "rsa-crypt").encrypt(INPUT);
    final Crypter decrypter = new Crypter(new PkcsKeyReader(
        KeyPurpose.DECRYPT_AND_ENCRYPT, pkcs8KeyStream, RsaPadding.OAEP, "pass"));
    assertEquals(INPUT, decrypter.decrypt(ciphertext));

    // Try with corrupted ciphertext
    final byte[] ciphertextBytes = Base64Coder.decodeWebSafe(ciphertext);
    ciphertextBytes[ciphertextBytes.length / 2] ^= 0xFF;
    try {
      decrypter.decrypt(Base64Coder.encodeWebSafe(ciphertextBytes));
    } catch (KeyczarException e) {
      assertTrue(e.getCause() instanceof BadPaddingException);
    }
  }

  private void doTestSignImport(String keyType, InputStream pkcs8KeyStream) throws Exception {
    RsaPadding padding = RsaPadding.OAEP;
    if (keyType.equals("dsa")) {
      padding = null;
    }

    final String signature = new Signer(TEST_DATA + keyType + "-sign").sign(INPUT);
    final Verifier verifier = new Verifier(
        new PkcsKeyReader(KeyPurpose.SIGN_AND_VERIFY, pkcs8KeyStream, padding, "pass"));
    assertTrue(verifier.verify(INPUT, signature));

    // Try with corrupted signature
    final byte[] signatureBytes = Base64Coder.decodeWebSafe(signature);
    signatureBytes[signatureBytes.length / 2] ^= 0xFF;
    assertFalse(verifier.verify(INPUT, Base64Coder.encodeWebSafe(signatureBytes)));

    // Try with corrupted message
    assertFalse(verifier.verify("wrong input", signature));
  }

  private InputStream getPkcs8KeyStream(String keyType, String fileFormat, String keyPurpose)
      throws FileNotFoundException {
    return new FileInputStream(TEST_DATA + keyType + "-" + keyPurpose + "-pkcs8." + fileFormat);
  }

  /**
   * An input stream that corrupts every tenth byte by inverting it.
   */
  private class CorruptedStream extends InputStream {
    private final InputStream inStream;
    private int count = 0;

    public CorruptedStream(InputStream inStream) {
      this.inStream = inStream;
    }

    @Override
    public int read() throws IOException {
      int b = inStream.read();
      if (b == -1 || ((++count % 10) != 0)) {
        return b;
      } else {
        return (byte)(b ^ 0xFF);
      }
    }
  }
}
TOP

Related Classes of org.keyczar.PkcsImportTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-20639858-1', 'auto'); ga('send', 'pageview');