/**
* This class represents an NDN KeyLocator object.
* Copyright (C) 2014-2016 Regents of the University of California.
* @author: Meki Cheraoui
* @author: Jeff Thompson <jefft0@remap.ucla.edu>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* A copy of the GNU Lesser General Public License is in the file COPYING.
*/
/** @ignore */
var Blob = require('./util/blob.js').Blob; /** @ignore */
var ChangeCounter = require('./util/change-counter.js').ChangeCounter; /** @ignore */
var Name = require('./name.js').Name;
/**
* KeyLocator
*/
var KeyLocatorType = {
KEYNAME: 1,
KEY_LOCATOR_DIGEST: 2
};
exports.KeyLocatorType = KeyLocatorType;
/**
* @constructor
*/
var KeyLocator = function KeyLocator(input, type)
{
if (typeof input === 'object' && input instanceof KeyLocator) {
// Copy from the input KeyLocator.
this.type_ = input.type_;
this.keyName_ = new ChangeCounter(new Name(input.getKeyName()));
this.keyData_ = input.keyData_;
}
else {
this.type_ = type;
this.keyName_ = new ChangeCounter(new Name());
this.keyData_ = new Blob();
if (type == KeyLocatorType.KEYNAME)
this.keyName_.set(typeof input === 'object' && input instanceof Name ?
new Name(input) : new Name());
else if (type == KeyLocatorType.KEY_LOCATOR_DIGEST)
this.keyData_ = new Blob(input);
}
this.changeCount_ = 0;
};
exports.KeyLocator = KeyLocator;
/**
* Get the key locator type. If KeyLocatorType.KEYNAME, you may also
* getKeyName(). If KeyLocatorType.KEY_LOCATOR_DIGEST, you may also
* getKeyData() to get the digest.
* @returns {number} The key locator type, or null if not specified.
*/
KeyLocator.prototype.getType = function() { return this.type_; };
/**
* Get the key name. This is meaningful if getType() is KeyLocatorType.KEYNAME.
* @returns {Name} The key name. If not specified, the Name is empty.
*/
KeyLocator.prototype.getKeyName = function()
{
return this.keyName_.get();
};
/**
* Get the key data. If getType() is KeyLocatorType.KEY_LOCATOR_DIGEST, this is
* the digest bytes.
* @returns {Blob} The key data, or null if not specified.
*/
KeyLocator.prototype.getKeyData = function()
{
return this.keyData_;
};
/**
* @deprecated Use getKeyData. This method returns a Buffer which is the former
* behavior of getKeyData, and should only be used while updating your code.
*/
KeyLocator.prototype.getKeyDataAsBuffer = function()
{
return this.getKeyData().buf();
};
/**
* Set the key locator type. If KeyLocatorType.KEYNAME, you must also
* setKeyName(). If KeyLocatorType.KEY_LOCATOR_DIGEST, you must also
* setKeyData() to the digest.
* @param {number} type The key locator type. If null, the type is unspecified.
*/
KeyLocator.prototype.setType = function(type)
{
this.type_ = type;
++this.changeCount_;
};
/**
* Set key name to a copy of the given Name. This is the name if getType()
* is KeyLocatorType.KEYNAME.
* @param {Name} name The key name which is copied.
*/
KeyLocator.prototype.setKeyName = function(name)
{
this.keyName_.set(typeof name === 'object' && name instanceof Name ?
new Name(name) : new Name());
++this.changeCount_;
};
/**
* Set the key data to the given value. This is the digest bytes if getType() is
* KeyLocatorType.KEY_LOCATOR_DIGEST.
* @param {Blob} keyData A Blob with the key data bytes.
*/
KeyLocator.prototype.setKeyData = function(keyData)
{
this.keyData_ = typeof keyData === 'object' && keyData instanceof Blob ?
keyData : new Blob(keyData);
++this.changeCount_;
};
/**
* Clear the keyData and set the type to not specified.
*/
KeyLocator.prototype.clear = function()
{
this.type_ = null;
this.keyName_.set(new Name());
this.keyData_ = new Blob();
++this.changeCount_;
};
/**
* If the signature is a type that has a KeyLocator (so that,
* getFromSignature will succeed), return true.
* Note: This is a static method of KeyLocator instead of a method of
* Signature so that the Signature base class does not need to be overloaded
* with all the different kinds of information that various signature
* algorithms may use.
* @param {Signature} signature An object of a subclass of Signature.
* @returns {boolean} True if the signature is a type that has a KeyLocator,
* otherwise false.
*/
KeyLocator.canGetFromSignature = function(signature)
{
return signature instanceof Sha256WithRsaSignature ||
signature instanceof HmacWithSha256Signature;
}
/**
* If the signature is a type that has a KeyLocator, then return it. Otherwise
* throw an error.
* @param {Signature} signature An object of a subclass of Signature.
* @returns {KeyLocator} The signature's KeyLocator. It is an error if signature
* doesn't have a KeyLocator.
*/
KeyLocator.getFromSignature = function(signature)
{
if (signature instanceof Sha256WithRsaSignature ||
signature instanceof HmacWithSha256Signature)
return signature.getKeyLocator();
else
throw new Error
("KeyLocator.getFromSignature: Signature type does not have a KeyLocator");
}
/**
* Get the change count, which is incremented each time this object (or a child
* object) is changed.
* @returns {number} The change count.
*/
KeyLocator.prototype.getChangeCount = function()
{
// Make sure each of the checkChanged is called.
var changed = this.keyName_.checkChanged();
if (changed)
// A child object has changed, so update the change count.
++this.changeCount_;
return this.changeCount_;
};
// Define properties so we can change member variable types and implement changeCount_.
Object.defineProperty(KeyLocator.prototype, "type",
{ get: function() { return this.getType(); },
set: function(val) { this.setType(val); } });
/**
* @@deprecated Use getKeyData and setKeyData.
*/
Object.defineProperty(KeyLocator.prototype, "keyData",
{ get: function() { return this.getKeyDataAsBuffer(); },
set: function(val) { this.setKeyData(val); } });
// Put this last to avoid a require loop.
var Sha256WithRsaSignature = require('./sha256-with-rsa-signature.js').Sha256WithRsaSignature;
var HmacWithSha256Signature = require('./hmac-with-sha256-signature.js').HmacWithSha256Signature;