/** * Update block keys, only to be used in master mode */ synchronized boolean updateKeys() throws IOException { if (!isMaster) { return false; } LOG.info("Updating block keys"); removeExpiredKeys(); // set final expiry date of retiring currentKey allKeys.put(currentKey.getKeyId(), new BlockKey(currentKey.getKeyId(), timer.now() + keyUpdateInterval + tokenLifetime, currentKey.getKey())); // update the estimated expiry date of new currentKey currentKey = new BlockKey(nextKey.getKeyId(), timer.now() + 2 * keyUpdateInterval + tokenLifetime, nextKey.getKey()); allKeys.put(currentKey.getKeyId(), currentKey); // generate a new nextKey setSerialNo(serialNo + 1); nextKey = new BlockKey(serialNo, timer.now() + 3 * keyUpdateInterval + tokenLifetime, generateSecret()); allKeys.put(nextKey.getKeyId(), nextKey); return true; }
public static BlockKeyProto convert(BlockKey key) { byte[] encodedKey = key.getEncodedKey(); ByteString keyBytes = PBHelperClient.getByteString(encodedKey == null ? DFSUtilClient.EMPTY_BYTES : encodedKey); return BlockKeyProto.newBuilder().setKeyId(key.getKeyId()) .setKeyBytes(keyBytes).setExpiryDate(key.getExpiryDate()).build(); }
/** */ @Override public void readFields(DataInput in) throws IOException { isBlockTokenEnabled = in.readBoolean(); keyUpdateInterval = in.readLong(); tokenLifetime = in.readLong(); currentKey.readFields(in); this.allKeys = new BlockKey[in.readInt()]; for (int i = 0; i < allKeys.length; i++) { allKeys[i] = new BlockKey(); allKeys[i].readFields(in); } }
/** * Recreate an encryption key based on the given key id and nonce. * * @param keyId identifier of the secret key used to generate the encryption key. * @param nonce random value used to create the encryption key * @return the encryption key which corresponds to this (keyId, blockPoolId, nonce) * @throws InvalidEncryptionKeyException */ public byte[] retrieveDataEncryptionKey(int keyId, byte[] nonce) throws InvalidEncryptionKeyException { BlockKey key = null; synchronized (this) { key = allKeys.get(keyId); if (key == null) { throw new InvalidEncryptionKeyException("Can't re-compute encryption key" + " for nonce, since the required block key (keyID=" + keyId + ") doesn't exist. Current key: " + currentKey.getKeyId()); } } return createPassword(nonce, key.getKey()); }
/** Initialize block keys */ private synchronized void generateKeys() { if (!isMaster) { return; } /* * Need to set estimated expiry dates for currentKey and nextKey so that if * NN crashes, DN can still expire those keys. NN will stop using the newly * generated currentKey after the first keyUpdateInterval, however it may * still be used by DN and Balancer to generate new tokens before they get a * chance to sync their keys with NN. Since we require keyUpdInterval to be * long enough so that all live DN's and Balancer will sync their keys with * NN at least once during the period, the estimated expiry date for * currentKey is set to now() + 2 * keyUpdateInterval + tokenLifetime. * Similarly, the estimated expiry date for nextKey is one keyUpdateInterval * more. */ setSerialNo(serialNo + 1); currentKey = new BlockKey(serialNo, timer.now() + 2 * keyUpdateInterval + tokenLifetime, generateSecret()); setSerialNo(serialNo + 1); nextKey = new BlockKey(serialNo, timer.now() + 3 * keyUpdateInterval + tokenLifetime, generateSecret()); allKeys.put(currentKey.getKeyId(), currentKey); allKeys.put(nextKey.getKeyId(), nextKey); }
public ExportedBlockKeys(boolean isBlockTokenEnabled, long keyUpdateInterval, long tokenLifetime, BlockKey currentKey, BlockKey[] allKeys) { this.isBlockTokenEnabled = isBlockTokenEnabled; this.keyUpdateInterval = keyUpdateInterval; this.tokenLifetime = tokenLifetime; this.currentKey = currentKey == null ? new BlockKey() : currentKey; this.allKeys = allKeys == null ? new BlockKey[0] : allKeys; }
private synchronized void removeExpiredKeys() { long now = timer.now(); for (Iterator<Map.Entry<Integer, BlockKey>> it = allKeys.entrySet() .iterator(); it.hasNext();) { Map.Entry<Integer, BlockKey> e = it.next(); if (e.getValue().getExpiryDate() < now) { it.remove(); } } }
/** * Set block keys, only to be used in worker mode */ public synchronized void addKeys(ExportedBlockKeys exportedKeys) throws IOException { if (isMaster || exportedKeys == null) { return; } LOG.info("Setting block keys"); removeExpiredKeys(); this.currentKey = exportedKeys.getCurrentKey(); BlockKey[] receivedKeys = exportedKeys.getAllKeys(); for (int i = 0; i < receivedKeys.length; i++) { if (receivedKeys[i] != null) { this.allKeys.put(receivedKeys[i].getKeyId(), receivedKeys[i]); } } }
/** * Look up the token password/secret for the given block token identifier. * * @param identifier * the block token identifier to look up * @return token password/secret as byte[] * @throws InvalidToken */ @Override public byte[] retrievePassword(BlockTokenIdentifier identifier) throws InvalidToken { if (isExpired(identifier.getExpiryDate())) { throw new InvalidToken("Block token with " + identifier + " is expired."); } BlockKey key = null; synchronized (this) { key = allKeys.get(identifier.getKeyId()); } if (key == null) { throw new InvalidToken("Can't re-compute password for " + identifier + ", since the required block key (keyID=" + identifier.getKeyId() + ") doesn't exist."); } return createPassword(identifier.getBytes(), key.getKey()); }
/** * Generate a data encryption key for this block pool, using the current * BlockKey. * * @return a data encryption key which may be used to encrypt traffic * over the DataTransferProtocol */ public DataEncryptionKey generateDataEncryptionKey() { byte[] nonce = new byte[8]; nonceGenerator.nextBytes(nonce); BlockKey key = null; synchronized (this) { key = currentKey; } byte[] encryptionKey = createPassword(nonce, key.getKey()); return new DataEncryptionKey(key.getKeyId(), blockPoolId, nonce, encryptionKey, timer.now() + tokenLifetime, encryptionAlgorithm); }
/** Initialize block keys */ private synchronized void generateKeys() { if (!isMaster) return; /* * Need to set estimated expiry dates for currentKey and nextKey so that if * NN crashes, DN can still expire those keys. NN will stop using the newly * generated currentKey after the first keyUpdateInterval, however it may * still be used by DN and Balancer to generate new tokens before they get a * chance to sync their keys with NN. Since we require keyUpdInterval to be * long enough so that all live DN's and Balancer will sync their keys with * NN at least once during the period, the estimated expiry date for * currentKey is set to now() + 2 * keyUpdateInterval + tokenLifetime. * Similarly, the estimated expiry date for nextKey is one keyUpdateInterval * more. */ setSerialNo(serialNo + 1); currentKey = new BlockKey(serialNo, timer.now() + 2 * keyUpdateInterval + tokenLifetime, generateSecret()); setSerialNo(serialNo + 1); nextKey = new BlockKey(serialNo, timer.now() + 3 * keyUpdateInterval + tokenLifetime, generateSecret()); allKeys.put(currentKey.getKeyId(), currentKey); allKeys.put(nextKey.getKeyId(), nextKey); }
public ExportedBlockKeys() { this(false, 0, 0, new BlockKey(), new BlockKey[0]); }
private synchronized void removeExpiredKeys() { long now = timer.now(); for (Iterator<Map.Entry<Integer, BlockKey>> it = allKeys.entrySet() .iterator(); it.hasNext();) { Map.Entry<Integer, BlockKey> e = it.next(); if (e.getValue().getExpiryDate() < now) { it.remove(); } } }
/** * Set block keys, only to be used in slave mode */ public synchronized void addKeys(ExportedBlockKeys exportedKeys) throws IOException { if (isMaster || exportedKeys == null) return; LOG.info("Setting block keys"); removeExpiredKeys(); this.currentKey = exportedKeys.getCurrentKey(); BlockKey[] receivedKeys = exportedKeys.getAllKeys(); for (int i = 0; i < receivedKeys.length; i++) { if (receivedKeys[i] == null) continue; this.allKeys.put(receivedKeys[i].getKeyId(), receivedKeys[i]); } }
/** * Look up the token password/secret for the given block token identifier. * * @param identifier * the block token identifier to look up * @return token password/secret as byte[] * @throws InvalidToken */ @Override public byte[] retrievePassword(BlockTokenIdentifier identifier) throws InvalidToken { if (isExpired(identifier.getExpiryDate())) { throw new InvalidToken("Block token with " + identifier.toString() + " is expired."); } BlockKey key = null; synchronized (this) { key = allKeys.get(identifier.getKeyId()); } if (key == null) { throw new InvalidToken("Can't re-compute password for " + identifier.toString() + ", since the required block key (keyID=" + identifier.getKeyId() + ") doesn't exist."); } return createPassword(identifier.getBytes(), key.getKey()); }
public static BlockKeyProto convert(BlockKey key) { byte[] encodedKey = key.getEncodedKey(); ByteString keyBytes = ByteString.copyFrom(encodedKey == null ? DFSUtil.EMPTY_BYTES : encodedKey); return BlockKeyProto.newBuilder().setKeyId(key.getKeyId()) .setKeyBytes(keyBytes).setExpiryDate(key.getExpiryDate()).build(); }
/** * Create a new password/secret for the given block token identifier. * * @param identifier * the block token identifier * @return token password/secret */ @Override protected byte[] createPassword(BlockTokenIdentifier identifier) { BlockKey key = null; synchronized (this) { key = currentKey; } if (key == null) { throw new IllegalStateException("currentKey hasn't been initialized."); } identifier.setExpiryDate(timer.now() + tokenLifetime); identifier.setKeyId(key.getKeyId()); if (LOG.isDebugEnabled()) { LOG.debug("Generating block token for " + identifier); } return createPassword(identifier.getBytes(), key.getKey()); }
/** * Update block keys, only to be used in master mode */ synchronized boolean updateKeys() throws IOException { if (!isMaster) return false; LOG.info("Updating block keys"); removeExpiredKeys(); // set final expiry date of retiring currentKey allKeys.put(currentKey.getKeyId(), new BlockKey(currentKey.getKeyId(), timer.now() + keyUpdateInterval + tokenLifetime, currentKey.getKey())); // update the estimated expiry date of new currentKey currentKey = new BlockKey(nextKey.getKeyId(), timer.now() + 2 * keyUpdateInterval + tokenLifetime, nextKey.getKey()); allKeys.put(currentKey.getKeyId(), currentKey); // generate a new nextKey setSerialNo(serialNo + 1); nextKey = new BlockKey(serialNo, timer.now() + 3 * keyUpdateInterval + tokenLifetime, generateSecret()); allKeys.put(nextKey.getKeyId(), nextKey); return true; }