1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /**
   6  * Licensed to the Apache Software Foundation (ASF) under one
   7  * or more contributor license agreements. See the NOTICE file
   8  * distributed with this work for additional information
   9  * regarding copyright ownership. The ASF licenses this file
  10  * to you under the Apache License, Version 2.0 (the
  11  * "License"); you may not use this file except in compliance
  12  * with the License. You may obtain a copy of the License at
  13  *
  14  * http://www.apache.org/licenses/LICENSE-2.0
  15  *
  16  * Unless required by applicable law or agreed to in writing,
  17  * software distributed under the License is distributed on an
  18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  19  * KIND, either express or implied. See the License for the
  20  * specific language governing permissions and limitations
  21  * under the License.
  22  */
  23 package com.sun.org.apache.xml.internal.security.keys.content;
  24 
  25 import java.security.KeyFactory;
  26 import java.security.NoSuchAlgorithmException;
  27 import java.security.PublicKey;
  28 import java.security.spec.InvalidKeySpecException;
  29 import java.security.spec.X509EncodedKeySpec;
  30 
  31 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
  32 import com.sun.org.apache.xml.internal.security.utils.Constants;
  33 import com.sun.org.apache.xml.internal.security.utils.Signature11ElementProxy;
  34 import org.w3c.dom.Document;
  35 import org.w3c.dom.Element;
  36 
  37 /**
  38  * Provides content model support for the <code>dsig11:DEREncodedKeyvalue</code> element.
  39  * 
  40  * @author Brent Putman (putmanb@georgetown.edu)
  41  */
  42 public class DEREncodedKeyValue extends Signature11ElementProxy implements KeyInfoContent {
  43 
  44     /** JCA algorithm key types supported by this implementation. */
  45     public static final String supportedKeyTypes[] = { "RSA", "DSA", "EC"};
  46 
  47     /**
  48      * Constructor DEREncodedKeyValue
  49      *
  50      * @param element
  51      * @param BaseURI
  52      * @throws XMLSecurityException
  53      */
  54     public DEREncodedKeyValue(Element element, String BaseURI) throws XMLSecurityException {
  55         super(element, BaseURI);
  56     }
  57 
  58     /**
  59      * Constructor DEREncodedKeyValue
  60      *
  61      * @param doc
  62      * @param publicKey
  63      * @throws XMLSecurityException
  64      */
  65     public DEREncodedKeyValue(Document doc, PublicKey publicKey) throws XMLSecurityException {
  66         super(doc);
  67 
  68         this.addBase64Text(getEncodedDER(publicKey));
  69     }
  70 
  71     /**
  72      * Constructor DEREncodedKeyValue
  73      *
  74      * @param doc
  75      * @param base64EncodedKey 
  76      */
  77     public DEREncodedKeyValue(Document doc, byte[] encodedKey) {
  78         super(doc);
  79 
  80         this.addBase64Text(encodedKey);
  81     }
  82 
  83     /**
  84      * Sets the <code>Id</code> attribute
  85      *
  86      * @param Id ID
  87      */
  88     public void setId(String id) {
  89         if (id != null) {
  90             this.constructionElement.setAttributeNS(null, Constants._ATT_ID, id);
  91             this.constructionElement.setIdAttributeNS(null, Constants._ATT_ID, true);
  92         } else {
  93             this.constructionElement.removeAttributeNS(null, Constants._ATT_ID);
  94         }
  95     }
  96 
  97     /**
  98      * Returns the <code>Id</code> attribute
  99      *
 100      * @return the <code>Id</code> attribute
 101      */
 102     public String getId() {
 103         return this.constructionElement.getAttributeNS(null, Constants._ATT_ID);
 104     }
 105 
 106     /** @inheritDoc */
 107     public String getBaseLocalName() {
 108         return Constants._TAG_DERENCODEDKEYVALUE;
 109     }
 110 
 111     /**
 112      * Method getPublicKey
 113      *
 114      * @return the public key
 115      * @throws XMLSecurityException
 116      */
 117     public PublicKey getPublicKey() throws XMLSecurityException {
 118         byte[] encodedKey = getBytesFromTextChild();
 119 
 120         // Iterate over the supported key types until one produces a public key.
 121         for (String keyType : supportedKeyTypes) {
 122             try {
 123                 KeyFactory keyFactory = KeyFactory.getInstance(keyType);
 124                 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
 125                 PublicKey publicKey = keyFactory.generatePublic(keySpec);
 126                 if (publicKey != null) {
 127                     return publicKey;
 128                 }
 129             } catch (NoSuchAlgorithmException e) {
 130                 // Do nothing, try the next type
 131             } catch (InvalidKeySpecException e) {
 132                 // Do nothing, try the next type
 133             }
 134         }
 135         throw new XMLSecurityException("DEREncodedKeyValue.UnsupportedEncodedKey");
 136     }
 137 
 138     /**
 139      * Method getEncodedDER
 140      *
 141      * @return the public key
 142      * @throws XMLSecurityException
 143      */
 144     protected byte[] getEncodedDER(PublicKey publicKey) throws XMLSecurityException {
 145         try {
 146             KeyFactory keyFactory = KeyFactory.getInstance(publicKey.getAlgorithm());
 147             X509EncodedKeySpec keySpec = keyFactory.getKeySpec(publicKey, X509EncodedKeySpec.class);
 148             return keySpec.getEncoded();
 149         } catch (NoSuchAlgorithmException e) {
 150             Object exArgs[] = { publicKey.getAlgorithm(), publicKey.getFormat(), publicKey.getClass().getName() };
 151             throw new XMLSecurityException("DEREncodedKeyValue.UnsupportedPublicKey", exArgs, e);
 152         } catch (InvalidKeySpecException e) {
 153             Object exArgs[] = { publicKey.getAlgorithm(), publicKey.getFormat(), publicKey.getClass().getName() };
 154             throw new XMLSecurityException("DEREncodedKeyValue.UnsupportedPublicKey", exArgs, e);
 155         }
 156     }
 157 
 158 }