blautenb    2003/11/13 01:28:55

  Modified:    src/org/apache/xml/security/encryption XMLCipher.java
               src/org/apache/xml/security/keys KeyInfo.java
  Log:
  Implementation of very basic ability to decrypt EncryptedKey
  
  Revision  Changes    Path
  1.8       +180 -9    
xml-security/src/org/apache/xml/security/encryption/XMLCipher.java
  
  Index: XMLCipher.java
  ===================================================================
  RCS file: 
/home/cvs/xml-security/src/org/apache/xml/security/encryption/XMLCipher.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- XMLCipher.java    12 Nov 2003 11:24:04 -0000      1.7
  +++ XMLCipher.java    13 Nov 2003 09:28:55 -0000      1.8
  @@ -194,6 +194,7 @@
       private Map enc2JCE;
        private Map enc2IV;
        private Key localKey;
  +     private Key localKEK;
   
       /**
        * Creates a new <code>XMLCipher</code>.
  @@ -286,6 +287,8 @@
           }
   
           instance.algorithm = transformation;
  +             instance.localKey = null;
  +             instance.localKEK = null;
   
           try {
               String jceAlgorithm = (String) 
instance.enc2JCE.get(transformation);
  @@ -331,6 +334,8 @@
   
           instance.algorithm = transformation;
                instance.requestedJCEProvider = provider;
  +             instance.localKey = null;
  +             instance.localKEK = null;
   
           try {
               String jceAlgorithm = (String) 
instance.enc2JCE.get(transformation);
  @@ -375,6 +380,24 @@
   
       }
   
  +     /**
  +      * Set a Key Encryption Key.
  +      * <p>
  +      * The Key Encryption Key (KEK) is used for encrypting/decrypting
  +      * EncryptedKey elements.  By setting this separately, the XMLCipher
  +      * class can know whether a key applies to the data part or wrapped key
  +      * part of an encrypted object.
  +      *
  +      * @param kek The key to use for de/encrypting key data
  +      */
  +
  +     public void setKEK(Key kek) {
  +
  +             localKEK = kek;
  +
  +     }
  +  
  +
       /**
        * Encrypts an <code>Element</code> and replaces it with its encrypted
        * counterpart in the context <code>Document</code>, that is, the
  @@ -829,8 +852,48 @@
                return (encryptedData);
       }
   
  +    /**
  +     * Returns an <code>EncryptedKey</code> interface. Use this operation if
  +     * you want to load an <code>EncryptedKey</code> structure from a DOM 
  +      * structure and manipulate the contents.
  +     *
  +     * @param context the context <code>Document</code>.
  +     * @param element the <code>Element</code> that will be loaded
  +     * @throws XMLEncryptionException.
  +     */
  +
  +    public EncryptedKey loadEncryptedKey(Document context, Element element) 
  +             throws XMLEncryptionException {
  +        logger.debug("Loading encrypted key...");
  +        if(null == context)
  +            logger.error("Context document unexpectedly null...");
  +        if(null == element)
  +            logger.error("Element unexpectedly null...");
  +        if(cipherMode != DECRYPT_MODE)
  +            logger.error("XMLCipher unexpectedly not in DECRYPT_MODE...");
  +
  +        instance.contextDocument = context;
  +        EncryptedKey encryptedKey = factory.newEncryptedKey(element);
  +
  +             return (encryptedKey);
  +    }
  +
  +    /**
  +     * Returns an <code>EncryptedKey</code> interface. Use this operation if
  +     * you want to load an <code>EncryptedKey</code> structure from a DOM 
  +      * structure and manipulate the contents.
  +      *
  +      * Assumes that the context document is the document that owns the 
element
  +     *
  +     * @param element the <code>Element</code> that will be loaded
  +     * @throws XMLEncryptionException.
  +     */
   
  +    public EncryptedKey loadEncryptedKey(Element element) 
  +             throws XMLEncryptionException {
   
  +             return (loadEncryptedKey(element.getOwnerDocument(), element));
  +    }
   
       /**
        * Decrypts an <code>EncryptedKey</code> object.
  @@ -840,6 +903,97 @@
           return (null);
       }
   
  +     /**
  +      * Decrypt a key from a passed in EncryptedKey structure
  +      *
  +      * @param encryptedKey Previously loaded EncryptedKey that needs
  +      * to be decrypted.
  +      * @param keyType a URI indicated the type of key that is wrapped
  +      * @returns a key corresponding to the give type
  +      */
  +
  +     public Key decryptKey(EncryptedKey encryptedKey, String algorithm) 
throws
  +                 XMLEncryptionException {
  +
  +        logger.debug("Decrypting key from previously loaded 
EncryptedKey...");
  +
  +        if(cipherMode != DECRYPT_MODE)
  +            logger.error("XMLCipher unexpectedly not in DECRYPT_MODE...");
  +
  +             if (localKEK == null) {
  +                     // For now take the easy apprach and just throw
  +                     logger.error("XMLCipher::decryptKey called without a 
KEK");
  +                     throw new XMLEncryptionException("Unable to decrypt 
without a KEK");
  +             }
  +
  +             CipherData cipherData = encryptedKey.getCipherData();
  +        String base64EncodedEncryptedOctets = null;
  +
  +        if (cipherData.getDataType() == CipherData.REFERENCE_TYPE) {
  +            // retrieve the cipher text
  +        } else if (cipherData.getDataType() == CipherData.VALUE_TYPE) {
  +            CipherValue cipherValue = cipherData.getCipherValue();
  +            base64EncodedEncryptedOctets = new 
String(cipherValue.getValue());
  +        } else {
  +            // complain...
  +        }
  +        logger.debug("Encrypted octets:\n" + base64EncodedEncryptedOctets);
  +
  +        byte[] encryptedBytes = null;
  +
  +        try {
  +                     encryptedBytes = 
Base64.decode(base64EncodedEncryptedOctets);
  +        } catch (Base64DecodingException bde) {
  +            throw new XMLEncryptionException("empty", bde);
  +        }
  +
  +             // Now create the working cipher
  +
  +             String jceAlgorithm = 
  +                     
JCEMapper.translateURItoJCEID(encryptedKey.getEncryptionMethod()
  +                                                                             
  .getAlgorithm()).getAlgorithmID();
  +             String provider;
  +
  +             if (requestedJCEProvider == null)
  +                     provider =
  +                             JCEMapper.translateURItoJCEID(encryptedKey
  +                                                                             
          .getEncryptionMethod()
  +                                                                             
          .getAlgorithm())
  +                             .getProviderId();
  +             else
  +                     provider = requestedJCEProvider;
  +
  +             String jceKeyAlgorithm = 
  +                     JCEMapper.getJCEKeyAlgorithmFromURI(algorithm, 
provider);
  +
  +             Cipher c;
  +             try {
  +                     c = Cipher.getInstance(jceAlgorithm, provider);
  +             } catch (NoSuchAlgorithmException nsae) {
  +                     throw new XMLEncryptionException("empty", nsae);
  +             } catch (NoSuchProviderException nspre) {
  +                     throw new XMLEncryptionException("empty", nspre);
  +             } catch (NoSuchPaddingException nspae) {
  +                     throw new XMLEncryptionException("empty", nspae);
  +             }
  +
  +             Key ret;
  +
  +             try {           
  +                     c.init(Cipher.UNWRAP_MODE, localKEK);
  +                     ret = c.unwrap(encryptedBytes, jceKeyAlgorithm, 
Cipher.SECRET_KEY);
  +                     
  +             } catch (InvalidKeyException ike) {
  +                     throw new XMLEncryptionException("empty", ike);
  +             } catch (NoSuchAlgorithmException nsae) {
  +                     throw new XMLEncryptionException("empty", nsae);
  +             }
  +
  +             return ret;
  +
  +    }
  +             
  +
       /**
        * Removes the contents of a <code>Node</code>.
        *
  @@ -870,6 +1024,12 @@
           if(cipherMode != DECRYPT_MODE)
               logger.error("XMLCipher unexpectedly not in DECRYPT_MODE...");
   
  +             if (localKey == null) {
  +                     // For now take the easy apprach and just throw
  +                     logger.error("XMLCipher::decryptElement called without 
a key");
  +                     throw new XMLEncryptionException("Unable to decrypt 
without a key");
  +             }
  +
           EncryptedData encryptedData = factory.newEncryptedData(element);
   
           CipherData cipherData = encryptedData.getCipherData();
  @@ -1508,10 +1668,16 @@
                        XMLEncryptionException {
               EncryptedData result = null;
   
  +                     NodeList dataElements = element.getElementsByTagNameNS(
  +                    EncryptionConstants.EncryptionSpecNS,
  +                    EncryptionConstants._TAG_CIPHERDATA);
  +
  +                     // Need to get the last CipherData found, as earlier 
ones will
  +                     // be for elements in the KeyInfo lists
  +
               Element dataElement =
  -                (Element) element.getElementsByTagNameNS(
  -                    EncryptionConstants.EncryptionSpecNS, 
  -                    EncryptionConstants._TAG_CIPHERDATA).item(0);
  +                             (Element) 
dataElements.item(dataElements.getLength() - 1);
  +
               CipherData data = newCipherData(dataElement);
   
               result = newEncryptedData(data);
  @@ -1599,11 +1765,12 @@
           EncryptedKey newEncryptedKey(Element element) throws
                   XMLEncryptionException {
               EncryptedKey result = null;
  -
  -            Element dataElement =
  -                (Element) element.getElementsByTagNameNS(
  +                     NodeList dataElements = element.getElementsByTagNameNS(
                       EncryptionConstants.EncryptionSpecNS,
  -                    EncryptionConstants._TAG_CIPHERDATA).item(0);
  +                    EncryptionConstants._TAG_CIPHERDATA);
  +            Element dataElement =
  +                             (Element) 
dataElements.item(dataElements.getLength() - 1);
  +
               CipherData data = newCipherData(dataElement);
               result = newEncryptedKey(data);
   
  @@ -1633,12 +1800,16 @@
                       encryptionMethodElement));
               }
   
  -            // TODO: Implement
               Element keyInfoElement =
                   (Element) element.getElementsByTagNameNS(
                       Constants.SignatureSpecNS, 
Constants._TAG_KEYINFO).item(0);
               if (null != keyInfoElement) {
  -                result.setKeyInfo(null);
  +                             try {
  +                                     result.setKeyInfo(new 
KeyInfo(keyInfoElement, null));
  +                             } catch (XMLSecurityException xse) {
  +                                     throw new XMLEncryptionException("Error 
loading Key Info", 
  +                                                                             
                         xse);
  +                             }
               }
   
               // TODO: Implement
  
  
  
  1.13      +28 -1     
xml-security/src/org/apache/xml/security/keys/KeyInfo.java
  
  Index: KeyInfo.java
  ===================================================================
  RCS file: 
/home/cvs/xml-security/src/org/apache/xml/security/keys/KeyInfo.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- KeyInfo.java      29 Apr 2003 21:36:53 -0000      1.12
  +++ KeyInfo.java      13 Nov 2003 09:28:55 -0000      1.13
  @@ -67,6 +67,8 @@
   import javax.crypto.SecretKey;
   
   import org.apache.xml.security.Init;
  +import org.apache.xml.security.encryption.EncryptedKey;
  +import org.apache.xml.security.encryption.XMLCipher;
   import org.apache.xml.security.exceptions.XMLSecurityException;
   import org.apache.xml.security.keys.content.KeyName;
   import org.apache.xml.security.keys.content.KeyValue;
  @@ -82,6 +84,7 @@
   import org.apache.xml.security.keys.keyresolver.KeyResolverSpi;
   import org.apache.xml.security.keys.storage.StorageResolver;
   import org.apache.xml.security.transforms.Transforms;
  +import org.apache.xml.security.utils.EncryptionConstants;
   import org.apache.xml.security.utils.Constants;
   import org.apache.xml.security.utils.IdResolver;
   import org.apache.xml.security.utils.SignatureElementProxy;
  @@ -588,6 +591,30 @@
            return null;
         }
      }
  +
  +   /**
  +     * Method itemEncryptedKey
  +     *
  +     * @param i
  +     *
  +     * @throws XMLEncryptionException
  +     */
  +
  +     public EncryptedKey itemEncryptedKey(int i) throws XMLSecurityException 
{
  +
  +             Element e = 
  +                     this.getChildElementLocalName(i, 
  +                                                                             
  EncryptionConstants.EncryptionSpecNS,
  +                                                                             
  EncryptionConstants._TAG_ENCRYPTEDKEY);
  +
  +             if (e != null) {
  +                     XMLCipher cipher = 
XMLCipher.getInstance(XMLCipher.TRIPLEDES);
  +                     return cipher.loadEncryptedKey(e);
  +             }
  +             else {
  +                     return null;
  +             }
  +     }
   
      /**
       * Method itemUnknownElement
  
  
  

Reply via email to