blob: 24e1f16e6f330dc34977fc511387533d9690750a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.security.storage;
import java.io.IOException;
/**
* This interface describes functionality provided by secure preferences. Secure
* preferences can be used to persist sensitive information in an encrypted form.
* <p>
* Logically, secure preferences combine functionality of a keyring (keystore) and
* {@link org.osgi.service.prefs.Preferences}.
* </p><p>
* For an excellent detailed description of the preferences functionality see
* {@link org.osgi.service.prefs.Preferences}. To recap in a short form, preferences
* provide a tree. Nodes on that tree can be used to specify context. For instance,
* root node could have a child node called "cvs" to store information related to CVS
* integration.
* </p><p>
* Each node can have a map of keys with associated values. For instance, to store
* password for the CVS repository located on eclipse.org we could use the following
* code:
* </p>
* <pre>
* ISecurePreferences root = SecurePreferencesFactory.getDefault();
* ISecurePreferences node = root.node("cvs/eclipse.org");
* node.put("password", myPassword, true);
* </pre>
* <p>
* This interface has the following differences from the {@link org.osgi.service.prefs.Preferences}:
* <ul>
* <li>get...() and put...() methods throw StorageException</li>
* <li>put...() methods have an extra argument bEncrypt</li>
* <li>Methods that used to throw BackingStoreException will be throwing more detailed StorageException</li>
* <li>Navigation on preferences tree will return ISecurePreferences, as opposing to Preferences</li>
* <li>flush() throws IOException</li>
* <li>sync() method is removed</li>
* </ul>
* </p><p>
* On the keyring side, when adding a key to the node, you can ask framework to encrypt it. Framework
* will lazily acquire password from password provider and use it to encrypt all new entries added
* to the secure preferences tree in this session.
* </p><p>
* It is worthwhile to reiterate that same limitations as {@link org.osgi.service.prefs.Preferences}
* apply to the node names. One non-trivial limitation is that node names can not contain forward
* slashes. For convenience, utility methods {@link EncodingUtils#encodeSlashes(String)} and
* {@link EncodingUtils#decodeSlashes(String)} are provided to work around this limitation.
* </p><p>
* Also note that secure preferences only intended to store relatively small size data, such as
* passwords. If you need to securely store large objects, consider encrypting such objects in
* a symmetric way using randomly generated password and use secure preferences to store the password.
* </p><p>
* If secure preferences were modified, the framework will automatically save them on shutdown.
* </p><p>
* This interface is not intended to be implemented or extended by clients.
* </p>
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ISecurePreferences {
/**
* Stores a value associated with the key in this node.
* @param key key with which the value is going to be associated
* @param value value to store
* @param encrypt <code>true</code> if value is to be encrypted, <code>false</code> value
* does not need to be encrypted
* @throws StorageException if exception occurred during encryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
* @throws NullPointerException if <code>key</code> is <code>null</code>.
*/
public void put(String key, String value, boolean encrypt) throws StorageException;
/**
* Retrieves a value associated with the key in this node. If the value was encrypted,
* it is decrypted.
* @param key key with this the value is associated
* @param def default value to return if the key is not associated with any value
* @return value associated the key. If value was stored in an encrypted form, it will be decrypted
* @throws StorageException if exception occurred during decryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public String get(String key, String def) throws StorageException;
/**
* Removes value associated with the key.
* @param key key with which a value is associated
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public void remove(String key);
/**
* Removes all values from this node.
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public void clear();
/**
* Returns keys that have associated values.
* @return keys that have associated values
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public String[] keys();
/**
* Returns names of children nodes
* @return names of children nodes
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public String[] childrenNames();
/**
* Returns parent of this node
* @return parent of this node
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public ISecurePreferences parent();
/**
* Returns node corresponding to the path specified. If such node does not
* exist, a new node is created.
* <p>
* If the node path is invalid, an {@link IllegalArgumentException} will be thrown
* by this method. The valid node path:
* <ul>
* <li>contains only ASCII characters between 32 and 126 (ASCII alphanumeric and printable
* characters);</li>
* <li>can not contain two or more consecutive forward slashes;</li>
* <li>can not end with a trailing forward slash.</li>
* </ul>
* </p>
* @see org.osgi.service.prefs.Preferences
* @see org.osgi.service.prefs.Preferences#node(String)
* @param pathName absolute or relative path to the node
* @return node corresponding to the path
* @throws IllegalArgumentException if the path name is invalid.
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public ISecurePreferences node(String pathName);
/**
* Checks if the node corresponding to the specified path exists in this tree
* of secure preferences.
* <p>
* If the node path is invalid, an {@link IllegalArgumentException} will be thrown
* by this method. See {@link #node(String)} for the description of what is considered
* to be a valid path.
* </p>
* @see org.osgi.service.prefs.Preferences
* @see org.osgi.service.prefs.Preferences#node(String)
* @param pathName absolute or relative path to the node
* @return <code>true</code> if node corresponding to the path exists, <code>false</code> otherwise
* @throws IllegalArgumentException if the path name is invalid.
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public boolean nodeExists(String pathName);
/**
* Removes this node from the tree of secure preferences.
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public void removeNode();
/**
* Returns name of this node.
* @return name of this node
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public String name();
/**
* Returns absolute path to this node.
* @return absolute path to this node
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public String absolutePath();
/**
* Saves the tree of secure preferences to the persistent storage. This method can be called
* on any node in the secure preference tree.
* @throws IOException if error occurred while saving secure preferences
*/
public void flush() throws IOException;
/**
* Stores a value associated with the key in this node.
* @param key key with which the value is going to be associated
* @param value value to store
* @param encrypt <code>true</code> if value is to be encrypted, <code>false</code> value
* does not need to be encrypted
* @throws StorageException if exception occurred during encryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
* @throws NullPointerException if <code>key</code> is <code>null</code>.
*/
public void putInt(String key, int value, boolean encrypt) throws StorageException;
/**
* Retrieves a value associated with the key in this node. If the value was encrypted,
* it is decrypted.
* @param key key with this the value is associated
* @param def default value to return if the key is not associated with any value
* @return value associated the key. If value was stored in an encrypted form, it will be decrypted
* @throws StorageException if exception occurred during decryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public int getInt(String key, int def) throws StorageException;
/**
* Stores a value associated with the key in this node.
* @param key key with which the value is going to be associated
* @param value value to store
* @param encrypt <code>true</code> if value is to be encrypted, <code>false</code> value
* does not need to be encrypted
* @throws StorageException if exception occurred during encryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
* @throws NullPointerException if <code>key</code> is <code>null</code>.
*/
public void putLong(String key, long value, boolean encrypt) throws StorageException;
/**
* Retrieves a value associated with the key in this node. If the value was encrypted,
* it is decrypted.
* @param key key with this the value is associated
* @param def default value to return if the key is not associated with any value
* @return value associated the key. If value was stored in an encrypted form, it will be decrypted
* @throws StorageException if exception occurred during decryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public long getLong(String key, long def) throws StorageException;
/**
* Stores a value associated with the key in this node.
* @param key key with which the value is going to be associated
* @param value value to store
* @param encrypt <code>true</code> if value is to be encrypted, <code>false</code> value
* does not need to be encrypted
* @throws StorageException if exception occurred during encryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
* @throws NullPointerException if <code>key</code> is <code>null</code>.
*/
public void putBoolean(String key, boolean value, boolean encrypt) throws StorageException;
/**
* Retrieves a value associated with the key in this node. If the value was encrypted,
* it is decrypted.
* @param key key with this the value is associated
* @param def default value to return if the key is not associated with any value
* @return value associated the key. If value was stored in an encrypted form, it will be decrypted
* @throws StorageException if exception occurred during decryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public boolean getBoolean(String key, boolean def) throws StorageException;
/**
* Stores a value associated with the key in this node.
* @param key key with which the value is going to be associated
* @param value value to store
* @param encrypt <code>true</code> if value is to be encrypted, <code>false</code> value
* does not need to be encrypted
* @throws StorageException if exception occurred during encryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
* @throws NullPointerException if <code>key</code> is <code>null</code>.
*/
public void putFloat(String key, float value, boolean encrypt) throws StorageException;
/**
* Retrieves a value associated with the key in this node. If the value was encrypted,
* it is decrypted.
* @param key key with this the value is associated
* @param def default value to return if the key is not associated with any value
* @return value associated the key. If value was stored in an encrypted form, it will be decrypted
* @throws StorageException if exception occurred during decryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public float getFloat(String key, float def) throws StorageException;
/**
* Stores a value associated with the key in this node.
* @param key key with which the value is going to be associated
* @param value value to store
* @param encrypt <code>true</code> if value is to be encrypted, <code>false</code> value
* does not need to be encrypted
* @throws StorageException if exception occurred during encryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
* @throws NullPointerException if <code>key</code> is <code>null</code>.
*/
public void putDouble(String key, double value, boolean encrypt) throws StorageException;
/**
* Retrieves a value associated with the key in this node. If the value was encrypted,
* it is decrypted.
* @param key key with this the value is associated
* @param def default value to return if the key is not associated with any value
* @return value associated the key. If value was stored in an encrypted form, it will be decrypted
* @throws StorageException if exception occurred during decryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public double getDouble(String key, double def) throws StorageException;
/**
* Stores a value associated with the key in this node.
* @param key key with which the value is going to be associated
* @param value value to store
* @param encrypt <code>true</code> if value is to be encrypted, <code>false</code> value
* does not need to be encrypted
* @throws StorageException if exception occurred during encryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
* @throws NullPointerException if <code>key</code> is <code>null</code>.
*/
public void putByteArray(String key, byte[] value, boolean encrypt) throws StorageException;
/**
* Retrieves a value associated with the key in this node. If the value was encrypted,
* it is decrypted.
* @param key key with this the value is associated
* @param def default value to return if the key is not associated with any value
* @return value associated the key. If value was stored in an encrypted form, it will be decrypted
* @throws StorageException if exception occurred during decryption
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public byte[] getByteArray(String key, byte[] def) throws StorageException;
/**
* Specifies if value associated with the key is encrypted.
* @param key key with which a value is associated
* @return <code>true</code> if value is encrypted, <code>false</code> otherwise
* @throws StorageException if stored data is invalid
* @throws IllegalStateException if this node (or an ancestor) has been removed with
* the {@link #removeNode()} method.
*/
public boolean isEncrypted(String key) throws StorageException;
}