This class implements a basic Group-based access control scheme. More...
Public Member Functions | |
GroupAccessControlManager (ContentName namespace) throws IOException | |
GroupAccessControlManager (ContentName namespace, CCNHandle handle) throws IOException | |
GroupAccessControlManager (ContentName namespace, ContentName groupStorage, ContentName userStorage) throws IOException | |
GroupAccessControlManager (ContentName namespace, ContentName groupStorage, ContentName userStorage, CCNHandle handle) throws IOException | |
GroupAccessControlManager (ContentName namespace, ContentName[] groupStorage, ContentName[] userStorage, CCNHandle handle) throws IOException | |
boolean | initialize (AccessControlPolicyMarkerObject policyInformation, CCNHandle handle) throws IOException |
GroupManager | groupManager () |
void | registerGroupStorage (ContentName groupStorage) throws IOException |
void | registerGroupStorage (ParameterizedName pName) |
void | registerUserStorage (ContentName userStorage) throws ContentEncodingException |
void | registerUserStorage (ParameterizedName userStorage) |
ParameterizedName | getUserStorage (ContentName userName) |
ParameterizedName | getUserStorage (byte[] distinguisingHash) |
GroupManager | groupManager (byte[] distinguishingHash) |
GroupManager | groupManager (ContentName prefixName) |
boolean | isGroupName (ContentName principalPublicKeyName) |
ContentName | groupPublicKeyName (ContentName principalName) |
ContentName | userPublicKeyName (ContentName principalName) |
Tuple< ContentName, String > | parsePrefixAndFriendlyNameFromPublicKeyName (ContentName principalPublicKeyName) |
ContentName | getPrincipalPublicKeyName (byte[] distinguishingHash, String friendlyName) |
void | publishMyIdentity (ContentName identity, PublicKey myPublicKey) throws InvalidKeyException, ContentEncodingException, IOException |
Publish my identity (i.e. | |
void | addMyIdentity (ContentName identity) |
Add an identity to my set. | |
void | publishUserIdentity (String userName, PublicKey userPublicKey) throws IOException, MalformedContentNameStringException |
Publish the specified identity (i.e. | |
boolean | haveIdentity (ContentName userName) |
String | nodeKeyLabel () |
PublicKeyObject | getLatestKeyForPrincipal (Link principal) throws ContentDecodingException, IOException |
Get the latest key for a specified principal TODO shortcut slightly -- the principal we have cached might not meet the constraints of the link. | |
ACLObject | initializeNamespace (ACL rootACL) throws InvalidKeyException, ContentEncodingException, ContentNotReadyException, ContentGoneException, IOException |
Creates the root ACL for _namespace. | |
ACLObject | getEffectiveACLObject (ContentName nodeName) throws ContentDecodingException, IOException |
Retrieves the latest version of an ACL effective at this node, either stored here or at one of its ancestors. | |
ACLObject | getACLObjectForNode (ContentName aclNodeName) throws ContentDecodingException, IOException |
Try to pull an ACL for a particular node. | |
ACLObject | getACLObjectForNodeIfExists (ContentName aclNodeName) throws ContentDecodingException, IOException |
Try to pull an ACL for a specified node if it exists. | |
ACL | getEffectiveACL (ContentName nodeName) throws ContentNotReadyException, ContentGoneException, ContentDecodingException, IOException |
Get the effective ACL for a node specified by its name. | |
ACL | setACL (ContentName nodeName, ACL newACL) throws AccessDeniedException, InvalidKeyException, ContentNotReadyException, ContentGoneException, IOException, NoSuchAlgorithmException |
Adds an ACL to a node that doesn't have one, or replaces one that exists. | |
ACL | setACL (ContentName nodeName, ACL newACL, ACLObject effectiveACLObject) throws AccessDeniedException, InvalidKeyException, ContentNotReadyException, ContentGoneException, IOException, NoSuchAlgorithmException |
Adds an ACL to a node that doesn't have one, or replaces one that exists. | |
void | deleteACL (ContentName nodeName) throws ContentDecodingException, IOException, InvalidKeyException, NoSuchAlgorithmException |
Delete the ACL at this node if one exists, returning control to the next ACL upstream. | |
ACL | updateACL (ContentName nodeName, ArrayList< ACL.ACLOperation > ACLUpdates) throws ContentDecodingException, IOException, InvalidKeyException, NoSuchAlgorithmException |
Pulls the ACL for this node, if one exists, and modifies it to include the following changes, then stores the result using setACL, updating the node key if necessary in the process. | |
ACL | addReaders (ContentName nodeName, ArrayList< Link > newReaders) throws InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Add readers to a specified node. | |
ACL | removeReaders (ContentName nodeName, ArrayList< Link > removedReaders) throws InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Remove readers from a specified node. | |
ACL | addWriters (ContentName nodeName, ArrayList< Link > newWriters) throws InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Add writers to a specified node. | |
ACL | removeWriters (ContentName nodeName, ArrayList< Link > removedWriters) throws InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Remove writers from a specified node. | |
ACL | addManagers (ContentName nodeName, ArrayList< Link > newManagers) throws InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Add managers to a specified node. | |
ACL | removeManagers (ContentName nodeName, ArrayList< Link > removedManagers) throws InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Remove managers from a specified node. | |
NodeKey | getLatestNodeKeyForNode (ContentName nodeName) throws InvalidKeyException, AccessDeniedException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Write path: get the latest node key for a node. | |
NodeKey | getSpecificNodeKey (ContentName nodeKeyName, byte[] nodeKeyIdentifier) throws InvalidKeyException, AccessDeniedException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Read path: Retrieve a specific node key from a given location, as specified by a key it was used to wrap, and, if possible, find a key we can use to unwrap the node key. | |
NodeKey | getEffectiveNodeKey (ContentName nodeName) throws AccessDeniedException, InvalidKeyException, ContentEncodingException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Write path: Get the effective node key in force at this node, used to derive keys to encrypt content. | |
NodeKey | getEffectiveNodeKey (ContentName nodeName, ACLObject effectiveACL) throws AccessDeniedException, InvalidKeyException, ContentEncodingException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Write path: Get the effective node key in force at this node, used to derive keys to encrypt content. | |
NodeKey | getFreshEffectiveNodeKey (ContentName nodeName) throws AccessDeniedException, InvalidKeyException, ContentDecodingException, ContentEncodingException, ContentNotReadyException, ContentGoneException, IOException, NoSuchAlgorithmException |
Like getEffectiveNodeKey(ContentName), except checks to see if node key is dirty and updates it if necessary. | |
boolean | nodeKeyIsDirty (ContentName theNodeKeyName) throws ContentDecodingException, IOException |
Do we need to update this node key? First, we look to see whether or not we know the key is dirty -- i.e. | |
boolean | dataKeyIsDirty (ContentName dataName) throws ContentNotReadyException, IOException |
Would we update this data key if we were doing reencryption? This one is simpler -- what node key is the data key encrypted under, and is that node key dirty? | |
NodeKey | getDataKeyWrappingKey (ContentName dataNodeName, PublisherPublicKeyDigest publisher) throws AccessDeniedException, InvalidKeyException, ContentEncodingException, IOException, NoSuchAlgorithmException |
Find the key to use to wrap a data key at this node for encryption. | |
Key | getDataKeyWrappingKey (ContentName dataNodeName, WrappedKeyObject wrappedDataKeyObject) throws InvalidKeyException, ContentNotReadyException, ContentGoneException, ContentEncodingException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Retrieve the node key wrapping this data key for decryption. | |
Key | getDataKeyWrappingKey (ContentName dataNodeName, ContentName wrappingKeyName, Key cachedWrappingKey) throws InvalidKeyException, ContentEncodingException |
Get the data key wrapping key if we happened to have cached a copy of the decryption key. | |
NodeKey | getNodeKeyForObject (ContentName nodeName, WrappedKeyObject wko) throws ContentNotReadyException, ContentGoneException, InvalidKeyException, ContentEncodingException, ContentDecodingException, IOException, NoSuchAlgorithmException |
boolean | isProtectedContent (ContentName name, PublisherPublicKeyDigest publisher, ContentType contentType, CCNHandle handle) |
Overrides the method of the same name in AccessControlManager. | |
boolean | haveKnownGroupMemberships () |
Static Public Member Functions | |
static AccessControlManager | create (ContentName name, ContentName profileName, ACL acl, ArrayList< ParameterizedName > parameterizedNames, KeyValueSet parameters, SaveType saveType, CCNHandle handle) throws IOException, InvalidKeyException |
Type-specific method to initialize group-based access control for a namespace. | |
Static Public Attributes | |
static final String | PROFILE_NAME_STRING = "/ccnx.org/ccn/profiles/security/access/group/GroupAccessControlProfile" |
Marker in a Root object that this is the profile we want. | |
static final String | DEFAULT_GROUP_KEY_ALGORITHM = "RSA" |
This algorithm must be capable of key wrap (RSA, ElGamal, etc). | |
static final int | DEFAULT_GROUP_KEY_LENGTH = 1024 |
static final String | NODE_KEY_LABEL = "Node Key" |
Protected Member Functions | |
NodeKey | findAncestorWithNodeKey (ContentName nodeName) throws InvalidKeyException, AccessDeniedException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Get the ancestor node key in force at this node (if we can decrypt it), including a key at this node itself. | |
NodeKey | getNodeKeyUsingInterposedACL (ContentName dataNodeName, ContentName wrappingKeyName, byte[] wrappingKeyIdentifier) throws ContentDecodingException, IOException, InvalidKeyException, NoSuchAlgorithmException |
We've looked for a node key we can decrypt at the expected node key location, but no dice. | |
NodeKey | generateNewNodeKey (ContentName nodeName, NodeKey oldEffectiveNodeKey, ACL effectiveACL) throws InvalidKeyException, ContentEncodingException, ContentNotReadyException, ContentGoneException, IOException |
Make a new node key and encrypt it under the given ACL. | |
Static Protected Attributes | |
static Comparator< byte[]> | byteArrayComparator = new ByteArrayCompare() |
Package Functions | |
NodeKey | getNodeKeyByVersionedName (ContentName nodeKeyName, byte[] nodeKeyIdentifier) throws AccessDeniedException, InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
We have the name of a specific version of a node key. |
This class implements a basic Group-based access control scheme.
For full details, see the CCNx Access Control Specification. Management of Groups and Group members is handled by the GroupManager and Group classes. This class handles management and updating of access control (node) keys stored in the name tree, and any operation that requires crawling that tree -- looking at more than one node at once. Operations on single nodes are handled by individual component classes (e.g. NodeKey).
TODO refactor this class and its use slightly; right now it is capable of handling multpile group and user namespaces, but it itself is limited to a single content namespace. This means that we have multiple GACMs, one per protected namespace; we should refactor so that we have one ACM of each type, and each manages multiple namespaces. This is not a large change, and might be more efficient.
This class is used in updating node keys and by getEffectiveNodeKey(ContentName). To achieve this, we walk up the tree for this node. At each point, we check to see if a node key exists. If one exists, we decrypt it if we know an appropriate key. Otherwise we return null.
We are going for a low-enumeration approach. We could enumerate node keys and see if we have rights on the latest version; but then we need to enumerate keys and figure out whether we have a copy of a key or one of its previous keys. If we don't know our group memberships, even if we enumerate the node key access, we don't know what groups we're a member of.
Node keys and ACLs evolve in the following fashion:
One could have the node key (NK) point to its ACL version, or vice versa, but they really do most efficiently evolve in parallel. One could have the ACL point to group versions, and update the ACL and NK together in the last case as well. In this last case, we want to update the NK only on next write; if we never write again, we never need to generate a new NK (unless we can delete). And we want to wait as long as possible, to skip NK updates with no corresponding writes. But, a writer needs to determine first what the most recent node key is for a given node, and then must determine whether or not that node key must be updated -- whether or not the most recent versions of groups are what that node key is encrypted under. Ideally we don't want to have it update the ACL, as that allows management access separation -- we can let writers write the node key without allowing them to write the ACL.
So, we can't store the group version information in the ACL. We don't necessarily want a writer to have to pull all the node key blocks to see what version of each group the node key is encrypted under.
We could name the node key blocks <prefix>/<access marker>="">/NK/#version/<group name>:<group key id>, if we could match on partial components, but we can't.
We can name the node key blocks <prefix>/<access marker>="">/NK/#version/<group key id> with a link pointing to that from NK/#version/<group name>.
For both read and write, we don't actually care what the ACL says. We only care what the node key is. Most efficient option, if we have a full key cache, is to list the node key blocks by key id used to encrypt them, and then pull one for a key in our cache. On the read side, we're looking at a specific version NK, and we might have rights by going through its later siblings. On the write side, we're looking at the latest version NK, and we should have rights to one of the key blocks, or we don't have rights. If we don't have a full key cache, we have to walk the access hierarchy. In that case, the most efficient thing to do is to pull the latest version of the ACL for that node (if we have a NK, we have an ACL, and vice versa, so we can enumerate NK and then pull ACLs). We then walk that ACL. If we know we are in one of the groups in that ACL, walk back to find the group key encrypting that node key. If we don't, walk the groups in that ACL to find out if we're in any of them. If we are, pull the current group key, see if it works, and start working backwards through group keys, populating the cache in the process, to find the relevant group key.
Right answer might be intentional containment. Besides the overall group key structures, we make a master list that points to the current versions of all the groups. That would have to be writable by anyone who is on the manage list for any group. That would let you get, easily, a single list indicating what groups are available and what their versions are. Unless NE lets you do that in a single pass, which would be better. (Enumerate name/latestversion, not just given name, enumerate versions.)
Operational Process:
read:
write:
enumerate key blocks and group names
ACL org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.addManagers | ( | ContentName | nodeName, | |
ArrayList< Link > | newManagers | |||
) | throws InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Add managers to a specified node.
nodeName | the name of the node | |
newManagers | the list of new managers |
IOException | ||
ContentDecodingException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
void org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.addMyIdentity | ( | ContentName | identity | ) |
Add an identity to my set.
Assume the key is already published.
ACL org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.addReaders | ( | ContentName | nodeName, | |
ArrayList< Link > | newReaders | |||
) | throws InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Add readers to a specified node.
nodeName | the name of the node | |
newReaders | the list of new readers |
IOException | ||
ContentDecodingException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
ACL org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.addWriters | ( | ContentName | nodeName, | |
ArrayList< Link > | newWriters | |||
) | throws InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Add writers to a specified node.
nodeName | the name of the node | |
newWriters | the list of new writers |
IOException | ||
ContentDecodingException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
static AccessControlManager org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.create | ( | ContentName | name, | |
ContentName | profileName, | |||
ACL | acl, | |||
ArrayList< ParameterizedName > | parameterizedNames, | |||
KeyValueSet | parameters, | |||
SaveType | saveType, | |||
CCNHandle | handle | |||
) | throws IOException, InvalidKeyException [static] |
Type-specific method to initialize group-based access control for a namespace.
Other subclasses of AccessControlManager, including subtypes of this one, should roll their own if necessary. This creates the type of access control manager specified in the policy; as long as it is a subtype of GroupAccessControlManager it will work fine. The subtype can specialize initializeNamespace to do additional setup if necessary.
namespace | ||
groupStorage | ||
userStorage | ||
handle |
IOException |
boolean org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.dataKeyIsDirty | ( | ContentName | dataName | ) | throws ContentNotReadyException, IOException |
Would we update this data key if we were doing reencryption? This one is simpler -- what node key is the data key encrypted under, and is that node key dirty?
This can be called by anyone -- the data about whether a data key is dirty is visible to anyone. Fixing a dirty key requires access, though.
dataName |
IOException | ||
ContentNotReadyException | ||
ContentDecodingException |
void org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.deleteACL | ( | ContentName | nodeName | ) | throws ContentDecodingException, IOException, InvalidKeyException, NoSuchAlgorithmException |
Delete the ACL at this node if one exists, returning control to the next ACL upstream.
We simply add a supserseded by block at this node, wrapping this key in the key of the upstream node. If we don't have read access at that node, throw AccessDeniedException. Then we write a GONE block here for the ACL, and a new node key version with a superseded by block. The superseded by block should probably be encrypted not with the ACL in force, but with the effective node key of the parent -- that will be derivable from the appropriate ACL, and will have the right semantics if a new ACL is interposed later. In the meantime, all the people with the newly in-force ancestor ACL should be able to read this content.
nodeName |
IOException | ||
ContentDecodingException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
NodeKey org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.findAncestorWithNodeKey | ( | ContentName | nodeName | ) | throws InvalidKeyException, AccessDeniedException, ContentDecodingException, IOException, NoSuchAlgorithmException [protected] |
Get the ancestor node key in force at this node (if we can decrypt it), including a key at this node itself.
We use the fact that ACLs and node keys are co-located; if you have one, you have the other.
nodeName | the name of the node |
IOException | ||
ContentDecodingException | ||
InvalidCipherTextException | ||
AccessDeniedException | ||
InvalidKeyException | ||
IOException | if something is wrong (e.g. no node keys at all) | |
NoSuchAlgorithmException |
NodeKey org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.generateNewNodeKey | ( | ContentName | nodeName, | |
NodeKey | oldEffectiveNodeKey, | |||
ACL | effectiveACL | |||
) | throws InvalidKeyException, ContentEncodingException, ContentNotReadyException, ContentGoneException, IOException [protected] |
Make a new node key and encrypt it under the given ACL.
If there is a previous node key (oldEffectiveNodeKey not null), it is wrapped in the new node key. Put all the blocks into the aggregating writer, but don't flush.
nodeName | ||
oldEffectiveNodeKey | ||
effectiveACL |
IOException | ||
ContentGoneException | ||
ContentNotReadyException | ||
ContentEncodingException | ||
InvalidKeyException |
ACLObject org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getACLObjectForNode | ( | ContentName | aclNodeName | ) | throws ContentDecodingException, IOException |
ACLObject org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getACLObjectForNodeIfExists | ( | ContentName | aclNodeName | ) | throws ContentDecodingException, IOException |
Key org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getDataKeyWrappingKey | ( | ContentName | dataNodeName, | |
ContentName | wrappingKeyName, | |||
Key | cachedWrappingKey | |||
) | throws InvalidKeyException, ContentEncodingException [virtual] |
Get the data key wrapping key if we happened to have cached a copy of the decryption key.
dataNodeName | ||
wrappedDataKeyObject | ||
cachedWrappingKey |
ContentEncodingException | ||
InvalidKeyException |
Implements org.ccnx.ccn.profiles.security.access.AccessControlManager.
Key org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getDataKeyWrappingKey | ( | ContentName | dataNodeName, | |
WrappedKeyObject | wrappedDataKeyObject | |||
) | throws InvalidKeyException, ContentNotReadyException, ContentGoneException, ContentEncodingException, ContentDecodingException, IOException, NoSuchAlgorithmException [virtual] |
Retrieve the node key wrapping this data key for decryption.
IOException | ||
ContentDecodingException | ||
ContentEncodingException | ||
ContentGoneException | ||
ContentNotReadyException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
Implements org.ccnx.ccn.profiles.security.access.AccessControlManager.
NodeKey org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getDataKeyWrappingKey | ( | ContentName | dataNodeName, | |
PublisherPublicKeyDigest | publisher | |||
) | throws AccessDeniedException, InvalidKeyException, ContentEncodingException, IOException, NoSuchAlgorithmException [virtual] |
Find the key to use to wrap a data key at this node for encryption.
This requires the current effective node key, and wrapping this data key in it. If the current node key is dirty, this causes a new one to be generated. If data at the current node is public, this returns null. Does not check to see whether content is excluded from encryption (e.g. by being access control data).
dataNodeName | the node for which to find a data key wrapping key | |
publisher | in case output key retrieval needs to be specialized by publisher |
newRandomDataKey |
AccessDeniedException | ||
InvalidKeyException | ||
ContentEncodingException | ||
IOException | ||
NoSuchAlgorithmException |
Implements org.ccnx.ccn.profiles.security.access.AccessControlManager.
ACL org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getEffectiveACL | ( | ContentName | nodeName | ) | throws ContentNotReadyException, ContentGoneException, ContentDecodingException, IOException |
ACLObject org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getEffectiveACLObject | ( | ContentName | nodeName | ) | throws ContentDecodingException, IOException |
NodeKey org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getEffectiveNodeKey | ( | ContentName | nodeName, | |
ACLObject | effectiveACL | |||
) | throws AccessDeniedException, InvalidKeyException, ContentEncodingException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Write path: Get the effective node key in force at this node, used to derive keys to encrypt content.
Vertical chaining. Works if you ask for node which has a node key. Hand in node with existing node key to avoid search.
nodeName |
AccessDeniedException | ||
ContentEncodingException | ||
ContentDecodingException | ||
IOException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
NodeKey org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getEffectiveNodeKey | ( | ContentName | nodeName | ) | throws AccessDeniedException, InvalidKeyException, ContentEncodingException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Write path: Get the effective node key in force at this node, used to derive keys to encrypt content.
Vertical chaining. Works if you ask for node which has a node key.
nodeName |
AccessDeniedException | ||
ContentEncodingException | ||
ContentDecodingException | ||
IOException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
NodeKey org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getFreshEffectiveNodeKey | ( | ContentName | nodeName | ) | throws AccessDeniedException, InvalidKeyException, ContentDecodingException, ContentEncodingException, ContentNotReadyException, ContentGoneException, IOException, NoSuchAlgorithmException |
Like getEffectiveNodeKey(ContentName), except checks to see if node key is dirty and updates it if necessary.
nodeName |
AccessDeniedException | ||
IOException | ||
ContentGoneException | ||
ContentNotReadyException | ||
ContentEncodingException | ||
ContentDecodingException | ||
AccessDeniedException,InvalidKeyException | ||
NoSuchAlgorithmException |
PublicKeyObject org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getLatestKeyForPrincipal | ( | Link | principal | ) | throws ContentDecodingException, IOException |
Get the latest key for a specified principal TODO shortcut slightly -- the principal we have cached might not meet the constraints of the link.
TODO principal is a link to a group or user name, need to use prefix/suffix to get actual public key
principal | the principal |
IOException | ||
ContentDecodingException |
NodeKey org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getLatestNodeKeyForNode | ( | ContentName | nodeName | ) | throws InvalidKeyException, AccessDeniedException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Write path: get the latest node key for a node.
nodeName | the name of the node |
IOException | ||
ContentDecodingException | ||
AccessDeniedException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
NodeKey org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getNodeKeyByVersionedName | ( | ContentName | nodeKeyName, | |
byte[] | nodeKeyIdentifier | |||
) | throws AccessDeniedException, InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException [package] |
We have the name of a specific version of a node key.
Now we just need to figure out which of our keys can be used to decrypt it.
nodeKeyName | ||
nodeKeyIdentifier |
IOException | ||
AccessDeniedException | ||
ContentDecodingException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
NodeKey org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getNodeKeyForObject | ( | ContentName | nodeName, | |
WrappedKeyObject | wko | |||
) | throws ContentNotReadyException, ContentGoneException, InvalidKeyException, ContentEncodingException, ContentDecodingException, IOException, NoSuchAlgorithmException |
nodeName | ||
wko |
ContentNotReadyException | ||
ContentGoneException | ||
InvalidKeyException | ||
ContentEncodingException | ||
ContentDecodingException | ||
IOException | ||
NoSuchAlgorithmException |
NodeKey org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getNodeKeyUsingInterposedACL | ( | ContentName | dataNodeName, | |
ContentName | wrappingKeyName, | |||
byte[] | wrappingKeyIdentifier | |||
) | throws ContentDecodingException, IOException, InvalidKeyException, NoSuchAlgorithmException [protected] |
We've looked for a node key we can decrypt at the expected node key location, but no dice.
See if a new ACL has been interposed granting us rights at a lower portion of the tree.
dataNodeName | ||
wrappingKeyName | ||
wrappingKeyIdentifier |
IOException | ||
ContentDecodingException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
NodeKey org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.getSpecificNodeKey | ( | ContentName | nodeKeyName, | |
byte[] | nodeKeyIdentifier | |||
) | throws InvalidKeyException, AccessDeniedException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Read path: Retrieve a specific node key from a given location, as specified by a key it was used to wrap, and, if possible, find a key we can use to unwrap the node key.
Throw an exception if there is no node key block at the appropriate name.
nodeKeyName | ||
nodeKeyIdentifier |
IOException | ||
ContentDecodingException | ||
AccessDeniedException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
ACLObject org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.initializeNamespace | ( | ACL | rootACL | ) | throws InvalidKeyException, ContentEncodingException, ContentNotReadyException, ContentGoneException, IOException |
boolean org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.isProtectedContent | ( | ContentName | name, | |
PublisherPublicKeyDigest | publisher, | |||
ContentType | contentType, | |||
CCNHandle | handle | |||
) |
Overrides the method of the same name in AccessControlManager.
GroupAccessControlManager specifies additional content that is not to be protected, such as group metadata.
Reimplemented from org.ccnx.ccn.profiles.security.access.AccessControlManager.
boolean org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.nodeKeyIsDirty | ( | ContentName | theNodeKeyName | ) | throws ContentDecodingException, IOException |
Do we need to update this node key? First, we look to see whether or not we know the key is dirty -- i.e.
does it have a superseded block (if it's gone, it will also have a superseded block). If not, we have to really check... Basically, we look at all the entities this node key is encrypted for, and determine whether any of them have a new version of their public key. If so, the node key is dirty.
The initial implementation of this will be simple and slow -- iterating through groups and assuming the active object system will keep updating itself whenever a new key appears. Eventually, we might want an index directory of all the versions of keys, so that one name enumeration request might give us information about whether keys have been updated. (Or some kind of aggregate versioning, that tell us a) whether any groups have changed their versions, or b) just the ones we care about have.)
This can be called by anyone -- the data about whether a node key is dirty is visible to anyone. Fixing a dirty node key requires access, though.
theNodeKeyName | this might be the name of the node where the NK is stored, or the NK name itself. We assume this exists -- that there at some point has been a node key here. TODO ephemeral node key naming |
IOException | ||
ContentDecodingException |
void org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.publishMyIdentity | ( | ContentName | identity, | |
PublicKey | myPublicKey | |||
) | throws InvalidKeyException, ContentEncodingException, IOException |
Publish my identity (i.e.
my public key) under a specified CCN name
identity | the name | |
myPublicKey | my public key |
InvalidKeyException | ||
ContentEncodingException | ||
IOException |
void org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.publishUserIdentity | ( | String | userName, | |
PublicKey | userPublicKey | |||
) | throws IOException, MalformedContentNameStringException |
Publish the specified identity (i.e.
the public key) of a specified user
userName | the name of the user | |
userPublicKey | the public key of the user |
IOException | ||
MalformedContentNameStringException |
ACL org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.removeManagers | ( | ContentName | nodeName, | |
ArrayList< Link > | removedManagers | |||
) | throws InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Remove managers from a specified node.
nodeName | the name of the node | |
removedManagers | the list of removed managers |
IOException | ||
ContentDecodingException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
ACL org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.removeReaders | ( | ContentName | nodeName, | |
ArrayList< Link > | removedReaders | |||
) | throws InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Remove readers from a specified node.
nodeName | the name of the node | |
removedReaders | the list of removed readers |
IOException | ||
ContentDecodingException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
ACL org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.removeWriters | ( | ContentName | nodeName, | |
ArrayList< Link > | removedWriters | |||
) | throws InvalidKeyException, ContentDecodingException, IOException, NoSuchAlgorithmException |
Remove writers from a specified node.
nodeName | the name of the node | |
removedWriters | the list of removed writers |
IOException | ||
ContentDecodingException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |
ACL org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.setACL | ( | ContentName | nodeName, | |
ACL | newACL, | |||
ACLObject | effectiveACLObject | |||
) | throws AccessDeniedException, InvalidKeyException, ContentNotReadyException, ContentGoneException, IOException, NoSuchAlgorithmException |
Adds an ACL to a node that doesn't have one, or replaces one that exists.
Just writes, doesn't bother to look at any current ACL. Does need to pull the effective node key at this node, though, to wrap the old ENK in a new node key. Gets handed in effective ACL, to avoid having to search.
nodeName | the name of the node | |
newACL | the new ACL |
InvalidKeyException | ||
IOException | ||
ContentGoneException | ||
ContentNotReadyException | ||
NoSuchAlgorithmException |
ACL org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.setACL | ( | ContentName | nodeName, | |
ACL | newACL | |||
) | throws AccessDeniedException, InvalidKeyException, ContentNotReadyException, ContentGoneException, IOException, NoSuchAlgorithmException |
Adds an ACL to a node that doesn't have one, or replaces one that exists.
Just writes, doesn't bother to look at any current ACL. Does need to pull the effective node key at this node, though, to wrap the old ENK in a new node key.
nodeName | the name of the node | |
newACL | the new ACL |
InvalidKeyException | ||
IOException | ||
ContentGoneException | ||
ContentNotReadyException | ||
NoSuchAlgorithmException |
ACL org.ccnx.ccn.profiles.security.access.group.GroupAccessControlManager.updateACL | ( | ContentName | nodeName, | |
ArrayList< ACL.ACLOperation > | ACLUpdates | |||
) | throws ContentDecodingException, IOException, InvalidKeyException, NoSuchAlgorithmException |
Pulls the ACL for this node, if one exists, and modifies it to include the following changes, then stores the result using setACL, updating the node key if necessary in the process.
nodeName | the name of the node | |
ACLUpdates | the updates to the ACL |
IOException | ||
ContentDecodingException | ||
InvalidKeyException | ||
NoSuchAlgorithmException |