Package javax.xml.crypto.test

Source Code of javax.xml.crypto.test.KeySelectors$ByteUtil

/*
* Copyright 2006 The Apache Software Foundation.
*
*  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.
*
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
*/
package javax.xml.crypto.test;

import java.io.*;
import java.security.*;
import java.security.cert.*;
import java.util.*;
import javax.xml.crypto.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dom.*;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.crypto.SecretKey;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.traversal.*;
import sun.security.util.DerValue;
import sun.security.x509.X500Name;

import junit.framework.*;

/**
* This is a class which supplies several KeySelector implementations
*
* @author Sean Mullan
* @author Valerie Peng
*/
public class KeySelectors {

    /**
     * KeySelector which would always return the secret key specified in its
     * constructor.
     */
    public static class SecretKeySelector extends KeySelector {
  private SecretKey key;
  public SecretKeySelector(byte[] bytes) {
      key = wrapBytes(bytes);
  }
  public SecretKeySelector(SecretKey key) {
      this.key = key;
  }
   
  public KeySelectorResult select(KeyInfo ki,
          KeySelector.Purpose purpose,
          AlgorithmMethod method,
          XMLCryptoContext context)
      throws KeySelectorException {
      return new SimpleKSResult(key);
  }
 
  private SecretKey wrapBytes(final byte[] bytes) {
      return new SecretKey() {
        public String getFormat() {
      return "RAW";
        }
       
        public String getAlgorithm() {
      return "Secret key";
        }
       
        public byte[] getEncoded() {
      return (byte[]) bytes.clone();
        }
    };
  }
    }

    /**
     * KeySelector which would retrieve the X509Certificate out of the
     * KeyInfo element and return the public key.
     * NOTE: If there is an X509CRL in the KeyInfo element, then revoked
     * certificate will be ignored.
     */
    public static class RawX509KeySelector extends KeySelector {
    
  public KeySelectorResult select(KeyInfo keyInfo,
          KeySelector.Purpose purpose,
          AlgorithmMethod method,
          XMLCryptoContext context)
      throws KeySelectorException {
      if (keyInfo == null) {
    throw new KeySelectorException("Null KeyInfo object!");
      }
      // search for X509Data in keyinfo
      Iterator iter = keyInfo.getContent().iterator();
      while (iter.hasNext()) {
    XMLStructure kiType = (XMLStructure) iter.next();
    if (kiType instanceof X509Data) {
        X509Data xd = (X509Data) kiType;
        Object[] entries = xd.getContent().toArray();
        X509CRL crl = null;
        // Looking for CRL before finding certificates
        for (int i = 0; (i<entries.length&&crl != null); i++) {
      if (entries[i] instanceof X509CRL) {
          crl = (X509CRL) entries[i];
      }
        }
        Iterator xi = xd.getContent().iterator();
        boolean hasCRL = false;
        while (xi.hasNext()) {
      Object o = xi.next();
      // skip non-X509Certificate entries
      if (o instanceof X509Certificate) {
          if ((purpose != KeySelector.Purpose.VERIFY) &&
        (crl != null) &&
        crl.isRevoked((X509Certificate)o)) {
        continue;
          } else {
        return new SimpleKSResult
            (((X509Certificate)o).getPublicKey());
          }
      }
        }
    }
      }
      throw new KeySelectorException("No X509Certificate found!");
  }
    }

    /**
     * KeySelector which would retrieve the public key out of the
     * KeyValue element and return it.
     * NOTE: If the key algorithm doesn't match signature algorithm,
     * then the public key will be ignored.
     */
    public static class KeyValueKeySelector extends KeySelector {
  public KeySelectorResult select(KeyInfo keyInfo,
          KeySelector.Purpose purpose,
          AlgorithmMethod method,
          XMLCryptoContext context)
      throws KeySelectorException {
      if (keyInfo == null) {
    throw new KeySelectorException("Null KeyInfo object!");
      }
      SignatureMethod sm = (SignatureMethod) method;
      List list = keyInfo.getContent();
     
      for (int i = 0; i < list.size(); i++) {
    XMLStructure xmlStructure = (XMLStructure) list.get(i);
    if (xmlStructure instanceof KeyValue) {
        PublicKey pk = null;
        try {
      pk = ((KeyValue)xmlStructure).getPublicKey();
        } catch (KeyException ke) {
      throw new KeySelectorException(ke);
        }
        // make sure algorithm is compatible with method
        if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) {
      return new SimpleKSResult(pk);
        }
    }
      }
      throw new KeySelectorException("No KeyValue element found!");
  }
 
  //@@@FIXME: this should also work for key types other than DSA/RSA
  static boolean algEquals(String algURI, String algName) {
      if (algName.equalsIgnoreCase("DSA") &&
    algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) {
    return true;
      } else if (algName.equalsIgnoreCase("RSA") &&
           algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1)) {
    return true;
      } else {
    return false;
      }
  }
    }

    /**
     * KeySelector which would perform special lookup as documented
     * by the ie/baltimore/merlin-examples testcases and return the
     * matching public key.
     */
    public static class CollectionKeySelector extends KeySelector {
  private CertificateFactory certFac;
  private File certDir;
  private Vector certs;
  private static final int MATCH_SUBJECT = 0;
  private static final int MATCH_ISSUER = 1;
  private static final int MATCH_SERIAL = 2;
  private static final int MATCH_SUBJECT_KEY_ID = 3;
  private static final int MATCH_CERTIFICATE = 4;
 
  public CollectionKeySelector(File dir) {
      certDir = dir;
      try {
    certFac = CertificateFactory.getInstance("X509");
      } catch (CertificateException ex) {
    // not going to happen
      }
      certs = new Vector();
      File[] files = new File(certDir, "certs").listFiles();
      for (int i = 0; i < files.length; i++) {
    try {
        certs.add((X509Certificate)certFac.generateCertificate
            (new FileInputStream(files[i])));
    } catch (Exception ex) {
        // ignore non-cert files
    }
      }
  }
 
  public Vector match(int matchType, Object value, Vector pool) {
      Vector matchResult = new Vector();
      for (int j=0; j < pool.size(); j++) {
    X509Certificate c = (X509Certificate) pool.get(j);
    switch (matchType) {
    case MATCH_SUBJECT:
        try {
            if (c.getSubjectDN().equals(new X500Name((String)value))) {
          matchResult.add(c);
            }
        } catch (IOException ioe) { }
        break;
    case MATCH_ISSUER:
        try {
            if (c.getIssuerDN().equals(new X500Name((String)value))) {
          matchResult.add(c);
            }
        } catch (IOException ioe) { }
        break;
    case MATCH_SERIAL:
        if (c.getSerialNumber().equals(value)) {
      matchResult.add(c);
        }
       
        break;
    case MATCH_SUBJECT_KEY_ID:
        byte[] extension = c.getExtensionValue("2.5.29.14");
        if (extension != null) {
      try {
          DerValue derValue = new DerValue(extension);
          DerValue derValue2 = new DerValue(derValue.getOctetString());
          byte[] extVal = derValue2.getOctetString();
         
          if (Arrays.equals(extVal, (byte[]) value)) {
        matchResult.add(c);
          }
      } catch (IOException ex) { }
        }
        break;
    case MATCH_CERTIFICATE:
        if (c.equals(value)) {
      matchResult.add(c);
        }
        break;
    }
      }
      return matchResult;
  }
 
  public KeySelectorResult select(KeyInfo keyInfo,
          KeySelector.Purpose purpose,
          AlgorithmMethod method,
          XMLCryptoContext context)
      throws KeySelectorException {
      if (keyInfo == null) {
    throw new KeySelectorException("Null KeyInfo object!");
      }
      Iterator iter = keyInfo.getContent().iterator();
      while (iter.hasNext()) {
    XMLStructure xmlStructure = (XMLStructure) iter.next();
    try {
        if (xmlStructure instanceof KeyName) {
      String name = ((KeyName)xmlStructure).getName();
      PublicKey pk = null;
      try {
          // Lookup the public key using the key name 'Xxx',
          // i.e. the public key is in "certs/xxx.crt".
          File certFile = new File(new File(certDir, "certs"),
        name.toLowerCase()+".crt");
          X509Certificate cert = (X509Certificate)
              certFac.generateCertificate
              (new FileInputStream(certFile));
          pk = cert.getPublicKey();
            } catch (FileNotFoundException e) {
          // assume KeyName contains subject DN and search
          // collection of certs for match
          Vector result = match(MATCH_SUBJECT, name, certs);
          int numOfMatches = (result==null? 0:result.size());
          if (numOfMatches != 1) {
              throw new KeySelectorException
            ((numOfMatches==0?"No":"More than one") +
             " match found");
          }
          pk =((X509Certificate)result.get(0)).getPublicKey();
      }
      return new SimpleKSResult(pk);
        } else if (xmlStructure instanceof RetrievalMethod) {
      // Lookup the public key using the retrievel method.
      // NOTE: only X509Certificate type is supported.
      RetrievalMethod rm = (RetrievalMethod) xmlStructure;
      String type = rm.getType();
      if (type.equals(X509Data.RAW_X509_CERTIFICATE_TYPE)) {
          String uri = rm.getURI();
          X509Certificate cert = (X509Certificate)
        certFac.generateCertificate
        (new FileInputStream(new File(certDir, uri)));
          return new SimpleKSResult(cert.getPublicKey());
      } else {
          throw new KeySelectorException
        ("Unsupported RetrievalMethod type");
      }
        } else if (xmlStructure instanceof X509Data) {
      List content = ((X509Data)xmlStructure).getContent();
      int size = content.size();
      Vector result = null;
      // Lookup the public key using the information
      // specified in X509Data element, i.e. searching
      // over the collection of certificate files under
      // "certs" subdirectory and return those match.
      for (int k = 0; k<size; k++) {
          Object obj = content.get(k);
          if (obj instanceof String) {
        result = match(MATCH_SUBJECT, obj, certs);
          } else if (obj instanceof byte[]) {
        result = match(MATCH_SUBJECT_KEY_ID, obj,
                 certs);
          } else if (obj instanceof X509Certificate) {
        result = match(MATCH_CERTIFICATE, obj, certs);
          } else if (obj instanceof X509IssuerSerial) {
        X509IssuerSerial is = (X509IssuerSerial) obj;
        result = match(MATCH_SERIAL,
                 is.getSerialNumber(), certs);
        result = match(MATCH_ISSUER,
                 is.getIssuerName(), result);
          } else {
        throw new KeySelectorException("Unsupported X509Data: " + obj);
          }
      }
      int numOfMatches = (result==null? 0:result.size());
      if (numOfMatches != 1) {
          throw new KeySelectorException
        ((numOfMatches==0?"No":"More than one") +
         " match found");
      }
      return new SimpleKSResult(((X509Certificate)
            result.get(0)).getPublicKey());
        }
    } catch (Exception ex) {
        throw new KeySelectorException(ex);
    }
      }
      throw new KeySelectorException("No matching key found!");
  }
    }
   
    public static class ByteUtil {
 
  private static String mapping = "0123456789ABCDEF";
  private static int numBytesPerRow = 6;
 
  private static String getHex(byte value) {
      int low = value & 0x0f;
      int high = ((value >> 4) & 0x0f);
      char[] res = new char[2];
      res[0] = mapping.charAt(high);
      res[1] = mapping.charAt(low);
      return new String(res);
  }

  public static String dumpArray(byte[] in) {
      int numDumped = 0;
      StringBuffer buf = new StringBuffer(512);
      buf.append("{");
      for (int i=0;i<(in.length/numBytesPerRow); i++) {
    for (int j=0; j<(numBytesPerRow); j++) {
        buf.append("(byte)0x" + getHex(in[i*numBytesPerRow+j]) +
             ", ");
    }
    numDumped += numBytesPerRow;
      }
      while (numDumped < in.length) {
    buf.append("(byte)0x" + getHex(in[numDumped]) + " ");
    numDumped += 1;
      }
      buf.append("}");
      return buf.toString();
  }
    }
}

class SimpleKSResult implements KeySelectorResult {
    private final Key key;
   
    SimpleKSResult(Key key) { this.key = key; }
   
    public Key getKey() { return key; }
}
TOP

Related Classes of javax.xml.crypto.test.KeySelectors$ByteUtil

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.