Public Member Functions | |
CCNMerkleTree (ContentObject[] contentObjects, PrivateKey signingKey) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException | |
Build a CCNMerkleTree from a set of leaf ContentObjects. | |
byte[] | rootSignature () |
Returns the root signature on the tree. | |
ContentName | segmentName (int leafIndex) |
Generate the name of segment leafIndex, where leafIndex is the leaf number in this tree. | |
SignedInfo | segmentSignedInfo (int leafIndex) |
Return the SignedInfo for a given segment. | |
Signature | segmentSignature (int leafIndex) |
Set the signature for a particular segment. | |
void | setSignatures () |
Sets the signatures of all the contained ContentObjects. | |
Static Public Attributes | |
static final String | DEFAULT_MHT_ALGORITHM = "SHA256MHT" |
Protected Member Functions | |
void | initializeTree (ContentObject[] contentObjects) throws NoSuchAlgorithmException |
A version of initializeTree to go with the CCNMerkleTree(ContentObject []) constructor. | |
Signature | computeSignature (int leafIndex) |
Construct the Signature for a given leaf. | |
void | computeLeafValues (ContentObject[] contentObjects) throws NoSuchAlgorithmException |
Compute the leaf values of the ContentObjects in this tree. | |
Static Protected Member Functions | |
static byte[] | computeRootSignature (byte[] root, PrivateKey signingKey) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException |
Compute the signature on the root node. | |
Package Attributes | |
byte[] | _rootSignature = null |
ContentObject[] | _segmentObjects = null |
It incorporates the CCN ContentName for an object at each node, so that names are authenticated as well as content in a way that intermediary CCN nodes can verify.
For each leaf node in the CCNMerkleTree, we compute its digest in exactly the same way we would compute the digest of a ContentObject node for signing on its own (incorporating the name, authentication metadata, and content). We then combine all these leaf digests together into a MerkleTree, and sign the root node.
To generate a leaf block digest, therefore, we need to know
So, we either need to hand in all the names, or have a function to call to get the name for each block.
Note: There is no requirement that a CCNMerkleTree be built only from the segments of a single piece of content, although that is the most common use. One can build and verify a CCNMerkleTree built out of an arbitrary set of ContentObjects; this may be a useful way of limiting the number of signatures generated on constrained platforms. Eventually the CCNSegmenter will be extended to handle such collections of arbitrary objects.
org.ccnx.ccn.impl.security.crypto.CCNMerkleTree.CCNMerkleTree | ( | ContentObject[] | contentObjects, | |
PrivateKey | signingKey | |||
) | throws NoSuchAlgorithmException, InvalidKeyException, SignatureException |
Build a CCNMerkleTree from a set of leaf ContentObjects.
contentObjects | must be at least 2 blocks, or will throw IllegalArgumentException. | |
signingKey | key to sign the root with |
NoSuchAlgorithmException | if key or DEFAULT_DIGEST_ALGORITHM are unknown | |
InvalidKeyException | if signingKey is invalid | |
SignatureException | if we cannot sign |
byte [] org.ccnx.ccn.impl.security.crypto.CCNMerkleTree.rootSignature | ( | ) |
Returns the root signature on the tree.
ContentName org.ccnx.ccn.impl.security.crypto.CCNMerkleTree.segmentName | ( | int | leafIndex | ) |
Generate the name of segment leafIndex, where leafIndex is the leaf number in this tree.
The overall index of leafIndex should be leafIndex + baseNameIndex().
leafIndex | the leaf whose blockName to generate |
SignedInfo org.ccnx.ccn.impl.security.crypto.CCNMerkleTree.segmentSignedInfo | ( | int | leafIndex | ) |
Return the SignedInfo for a given segment.
leafIndex | the index of the leaf whose SignedInfo we want |
Signature org.ccnx.ccn.impl.security.crypto.CCNMerkleTree.segmentSignature | ( | int | leafIndex | ) |
Set the signature for a particular segment.
leafIndex | the leaf segment to set the signature for |
void org.ccnx.ccn.impl.security.crypto.CCNMerkleTree.initializeTree | ( | ContentObject[] | contentObjects | ) | throws NoSuchAlgorithmException [protected] |
A version of initializeTree to go with the CCNMerkleTree(ContentObject []) constructor.
contentObjects | objects to build into the tree |
NoSuchAlgorithmException | if the default digest algorithm unknown |
Signature org.ccnx.ccn.impl.security.crypto.CCNMerkleTree.computeSignature | ( | int | leafIndex | ) | [protected] |
Construct the Signature for a given leaf.
This is composed of the rootSignature(), which is the same for all nodes, and the DER encoded MerklePath for this leaf as the witness.
leafIndex | the leaf to compute the signature for |
static byte [] org.ccnx.ccn.impl.security.crypto.CCNMerkleTree.computeRootSignature | ( | byte[] | root, | |
PrivateKey | signingKey | |||
) | throws InvalidKeyException, SignatureException, NoSuchAlgorithmException [static, protected] |
Compute the signature on the root node.
It's already a digest, so in theory we could just wrap it up in some PKCS#1 padding, encrypt it with our private key, and voila! A signature. But there are basically no crypto software packages that provide signature primitives that take already-digested data and just do the padding and encryption, and so we'd be asking anyone attempting to implement CCN MHT signing (including ourselves) to re-implement a very complicated wheel, across a number of signature algorithms. We might also want to sign with a key that does not support the digest algorithm we used to compute the root (for example, DSA). So take the computationally very slightly more expensive, but vastly simpler (implementation-wise) approach of taking our digest and signing it with a standard signing API -- which means digesting it one more time for the signature. So we sign (digest + encrypt) the root digest.
root | the root digest to sign | |
signingKey | the key to sign with |
InvalidKeyException | ||
SignatureException | ||
NoSuchAlgorithmException |
void org.ccnx.ccn.impl.security.crypto.CCNMerkleTree.computeLeafValues | ( | ContentObject[] | contentObjects | ) | throws NoSuchAlgorithmException [protected] |
Compute the leaf values of the ContentObjects in this tree.
contentObjects | the content |
NoSuchAlgorithmException | if the digestAlgorithm unknown |