View Javadoc

1   /*
2    * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.opensaml.xml.security.credential;
18  
19  import java.util.List;
20  
21  import org.opensaml.xml.Configuration;
22  import org.opensaml.xml.XMLObject;
23  import org.opensaml.xml.security.SecurityException;
24  import org.opensaml.xml.security.keyinfo.KeyInfoGenerator;
25  import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorFactory;
26  import org.opensaml.xml.security.keyinfo.KeyInfoHelper;
27  import org.opensaml.xml.signature.KeyInfo;
28  import org.opensaml.xml.signature.impl.KeyInfoBuilder;
29  import org.opensaml.xml.util.DatatypeHelper;
30  
31  
32  /**
33   * A factory implementation which produces instances of {@link KeyInfoGenerator} capable of 
34   * handling the information contained within a {@link Credential}.
35   * 
36   * All boolean options default to false.
37   */
38  public class BasicKeyInfoGeneratorFactory implements KeyInfoGeneratorFactory {
39      
40      /** The set of options configured for the factory. */
41      private BasicOptions options;
42      
43      /**
44       * Constructor.
45       * 
46       * All boolean options are initialzed as false;
47       */
48      public BasicKeyInfoGeneratorFactory() {
49          options = newOptions();
50      }
51      
52      /** {@inheritDoc} */
53      public Class<? extends Credential> getCredentialType() {
54          return Credential.class;
55      }
56  
57      /** {@inheritDoc} */
58      public boolean handles(Credential credential) {
59          // This top-level class can handle any Credential type, with output limited to basic Credential information
60          return true;
61      }
62  
63      /** {@inheritDoc} */
64      public KeyInfoGenerator newInstance() {
65          //TODO lock options during cloning ?
66          BasicOptions newOptions = options.clone();
67          return new BasicKeyInfoGenerator(newOptions);
68      }
69      
70      /**
71       * Get the option to emit the entity ID value in a Credential as a KeyName element.
72       * 
73       * @return return the option value
74       */
75      public boolean emitEntityIDAsKeyName() {
76          return options.emitEntityIDAsKeyName;
77      }
78  
79      /**
80       * Set the option to emit the entity ID value in a Credential as a KeyName element.
81       * 
82       * @param newValue the new option value to set
83       */
84      public void setEmitEntityIDAsKeyName(boolean newValue) {
85          options.emitEntityIDAsKeyName = newValue;
86      }
87  
88      /**
89       * Get the option to emit key names found in a Credential as KeyName elements.
90       * 
91       * @return the option value
92       */
93      public boolean emitKeyNames() {
94          return options.emitKeyNames;
95      }
96  
97      /**
98       * Set the option to emit key names found in a Credential as KeyName elements.
99       * 
100      * @param newValue the new option value to set
101      */
102     public void setEmitKeyNames(boolean newValue) {
103         options.emitKeyNames = newValue;
104     }
105 
106     /**
107      * Get the option to emit the value of {@link Credential#getPublicKey()} as a KeyValue element.
108      * 
109      * @return the option value
110      */
111     public boolean emitPublicKeyValue() {
112         return options.emitPublicKeyValue;
113     }
114 
115     /**
116      * Set the option to emit the value of {@link Credential#getPublicKey()} as a KeyValue element.
117      * 
118      * @param newValue the new option value to set
119      */
120     public void setEmitPublicKeyValue(boolean newValue) {
121         options.emitPublicKeyValue = newValue;
122         
123     }
124     
125     /**
126      * Get a new instance to hold options.  Used by the top-level superclass constructor.
127      * Subclasses <strong>MUST</strong> override to produce an instance of the appropriate 
128      * subclass of {@link BasicOptions}.
129      * 
130      * @return a new instance of factory/generator options
131      */
132     protected BasicOptions newOptions() {
133         return new BasicOptions();
134     }
135     
136     /**
137      * Get the options of this instance. Used by subclass constructors to get the options built by 
138      * the top-level class constructor with {@link #newOptions()}.
139      * 
140      * @return the options instance
141      */
142     protected BasicOptions getOptions() {
143         return options;
144     }
145     
146     /**
147      * An implementation of {@link KeyInfoGenerator} capable of  handling the information 
148      * contained within a {@link Credential}.
149     */
150     public class BasicKeyInfoGenerator implements KeyInfoGenerator {
151         
152         /** The set of options to be used by the generator.*/
153         private BasicOptions options;
154        
155         /** Builder for KeyInfo objects. */
156         private KeyInfoBuilder keyInfoBuilder;
157        
158         /**
159          * Constructor.
160          * 
161          * @param newOptions the options to be used by the generator
162          */
163         protected BasicKeyInfoGenerator(BasicOptions newOptions) {
164             options = newOptions;
165             keyInfoBuilder = 
166                 (KeyInfoBuilder) Configuration.getBuilderFactory().getBuilder(KeyInfo.DEFAULT_ELEMENT_NAME);
167         }
168 
169         /** {@inheritDoc} */
170         public KeyInfo generate(Credential credential) throws SecurityException {
171             KeyInfo keyInfo = keyInfoBuilder.buildObject();
172             
173             processKeyNames(keyInfo, credential);
174             processEntityID(keyInfo, credential);
175             processPublicKey(keyInfo, credential);
176             
177             List<XMLObject> children = keyInfo.getOrderedChildren();
178             if (children != null && children.size() > 0) {
179                 return keyInfo;
180             } else {
181                 return null;
182             }
183         }
184         
185         /** Process the values of {@link Credential#getKeyNames()}.
186          * 
187          * @param keyInfo the KeyInfo that is being built
188          * @param credential the Credential that is geing processed
189          */
190         protected void processKeyNames(KeyInfo keyInfo, Credential credential) {
191             if (options.emitKeyNames) {
192                 for (String keyNameValue : credential.getKeyNames()) {
193                     if ( ! DatatypeHelper.isEmpty(keyNameValue)) {
194                         KeyInfoHelper.addKeyName(keyInfo, keyNameValue);
195                     }
196                 }
197             }
198         }
199         
200         /** Process the value of {@link Credential#getEntityId()}.
201          * 
202          * @param keyInfo the KeyInfo that is being built
203          * @param credential the Credential that is geing processed
204          */
205         protected void processEntityID(KeyInfo keyInfo, Credential credential) {
206             if (options.emitEntityIDAsKeyName) {
207                 String keyNameValue = credential.getEntityId();
208                 if ( ! DatatypeHelper.isEmpty(keyNameValue)) {
209                     KeyInfoHelper.addKeyName(keyInfo, keyNameValue);
210                 }
211             }
212         }
213         
214         /** Process the value of {@link Credential#getPublicKey()}.
215          * 
216          * @param keyInfo the KeyInfo that is being built
217          * @param credential the Credential that is geing processed
218          */
219         protected void processPublicKey(KeyInfo keyInfo, Credential credential) {
220             if (options.emitPublicKeyValue) {
221                 if (credential.getPublicKey() != null) {
222                     KeyInfoHelper.addPublicKey(keyInfo, credential.getPublicKey());
223                 }
224             }
225         }
226     }
227     
228     /**
229      * Options to be used in the production of a {@link KeyInfo} from a {@link Credential}.
230      */
231     protected class BasicOptions implements Cloneable {
232         
233         /** Emit key names found in a Credential as KeyName elements. */
234         private boolean emitKeyNames;
235         
236         /** Emit the entity ID value in a Credential as a KeyName element. */
237         private boolean emitEntityIDAsKeyName;
238         
239         /** Emit the value of {@link Credential#getPublicKey()} as a KeyValue element. */
240         private boolean emitPublicKeyValue;
241         
242         /** {@inheritDoc} */
243         protected BasicOptions clone() {
244             try {
245                 return (BasicOptions) super.clone();
246             } catch (CloneNotSupportedException e) {
247                 // we know we're cloneable, so this will never happen
248                 return null;
249             }
250         }
251         
252     }
253 
254 }