Allow DSA public keys.

DSA can't be used for encryption with the bouncycastle library, so make
sure this situation is properly handled.
This commit is contained in:
Hugo Trippaers 2013-06-16 14:37:48 -07:00
parent 76d3c27bf4
commit b0ea02e65a
4 changed files with 143 additions and 41 deletions

View File

@ -509,18 +509,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
// update the password in vm_details table too
// Check if an SSH key pair was selected for the instance and if so
// use it to encrypt & save the vm password
String sshPublicKey = userVm.getDetail("SSH.PublicKey");
if (sshPublicKey != null && !sshPublicKey.equals("")
&& password != null && !password.equals("saved_password")) {
String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(
sshPublicKey, password);
if (encryptedPasswd == null) {
throw new CloudRuntimeException("Error encrypting password");
}
userVm.setDetail("Encrypted.Password", encryptedPasswd);
_vmDao.saveDetails(userVm);
}
encryptAndStorePassword(userVm, password);
} else {
throw new CloudRuntimeException(
"Failed to reset password for the virtual machine ");
@ -643,13 +632,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
if (template != null && template.getEnablePassword()) {
userVm.setPassword(password);
//update the encrypted password in vm_details table too
if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password")) {
String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password);
if (encryptedPasswd == null) {
throw new CloudRuntimeException("Error encrypting password");
}
userVm.setDetail("Encrypted.Password", encryptedPasswd);
}
encryptAndStorePassword(userVm, password);
}
_vmDao.saveDetails(userVm);
} else {
@ -3304,18 +3287,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
// Check if an SSH key pair was selected for the instance and if so
// use it to encrypt & save the vm password
String sshPublicKey = vm.getDetail("SSH.PublicKey");
if (sshPublicKey != null && !sshPublicKey.equals("")
&& password != null && !password.equals("saved_password")) {
String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(
sshPublicKey, password);
if (encryptedPasswd == null) {
throw new CloudRuntimeException("Error encrypting password");
}
vm.setDetail("Encrypted.Password", encryptedPasswd);
_vmDao.saveDetails(vm);
}
encryptAndStorePassword(vm, password);
params = new HashMap<VirtualMachineProfile.Param, Object>();
if (additionalParams != null) {
@ -4621,15 +4593,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
// update the password in vm_details table too
// Check if an SSH key pair was selected for the instance and if so
// use it to encrypt & save the vm password
String sshPublicKey = vm.getDetail("SSH.PublicKey");
if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password")) {
String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password);
if (encryptedPasswd == null) {
throw new CloudRuntimeException("VM reset is completed but error occurred when encrypting newly created password");
}
vm.setDetail("Encrypted.Password", encryptedPasswd);
_vmDao.saveDetails(vm);
}
encryptAndStorePassword(vm, password);
} else {
throw new CloudRuntimeException("VM reset is completed but failed to reset password for the virtual machine ");
}
@ -4717,5 +4681,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
if (vm.getState() == State.Running)
collectVmDiskStatistics(vm);
}
private void encryptAndStorePassword(UserVmVO vm, String password) {
String sshPublicKey = vm.getDetail("SSH.PublicKey");
if (sshPublicKey != null && !sshPublicKey.equals("")
&& password != null && !password.equals("saved_password")) {
if (!sshPublicKey.startsWith("ssh-rsa")) {
s_logger.warn("Only RSA public keys can be used to encrypt a vm password.");
return;
}
String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(
sshPublicKey, password);
if (encryptedPasswd == null) {
throw new CloudRuntimeException("Error encrypting password");
}
vm.setDetail("Encrypted.Password", encryptedPasswd);
_vmDao.saveDetails(vm);
}
}
}

View File

@ -82,7 +82,7 @@ public class SSHKeysHelper {
if (!keyMaterial.contains(" "))
keyMaterial = new String(Base64.decodeBase64(keyMaterial.getBytes()));
if (!keyMaterial.startsWith("ssh-rsa") || !keyMaterial.contains(" "))
if ((!keyMaterial.startsWith("ssh-rsa") && !keyMaterial.startsWith("ssh-dss")) || !keyMaterial.contains(" "))
return null;
String[] key = keyMaterial.split(" ");

View File

@ -0,0 +1,50 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.utils.crypto;
import static org.junit.Assert.*;
import org.junit.Test;
import com.cloud.utils.crypt.RSAHelper;
public class RSAHelperTest {
@Test
public void testEncryptWithRSA() {
String rsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2D2Cs0XAEqm+ajJpumIPrMpKp0CWtIW+8ZY2/MJCW" +
"hge1eY18u9I3PPnkMVJsTOaN0wQojjw4AkKgKjNZXA9wyUq56UyN/stmipu8zifWPgxQGDRkuzzZ6buk" +
"ef8q2Awjpo8hv5/0SRPJxQLEafESnUP+Uu/LUwk5VVC7PHzywJRUGFuzDl/uT72+6hqpL2YpC6aTl4/P" +
"2eDvUQhCdL9dBmUSFX8ftT53W1jhsaQl7mPElVgSCtWz3IyRkogobMPrpJW/IPKEiojKIuvNoNv4CDR6" +
"ybeVjHOJMb9wi62rXo+CzUsW0Y4jPOX/OykAm5vrNOhQhw0aaBcv5XVv8BRX";
String encryptedString = RSAHelper.encryptWithSSHPublicKey(rsaKey, "content");
assertNotNull(encryptedString);
}
@Test
public void testEncryptWithDSA() {
String dssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBALbaewDnzZ5AcGbZno7VW1m7Si3Q+yEANXZioVupfSwOP0q9aP2iV"+
"tyqq575JnUVZXMDR2Gr254F/qCJ0TKAvucN0gcd2XslX4jBcu1Z7s7YZf6d7fC58k0NE6/keokJNKhQO" +
"i56iirRzSA/YFrD64mzfq6rEmai0q7GjGGP0RT1AAAAFQDO5++6JonyqnoRkV9Yl1OaEOPjVwAAAIAYA" +
"tqtKtU/INlTIuL3wt3nyKzwPUnz3fqxP5Ger3OlRZsOahalTFt2OF5jGGmCunyBTRteOetZObr0QhUIF" +
"4bSDr6UiYYYbH1ES0ws/t1mDIeTh3UUHV1QYACN6c07FKyKLMtB9AthiG2FMLKCEedG3NeXItuNzsuQD" +
"+n/K1rzMAAAAIBi5SM4pFPiB7BvTZvARV56vrG5QNgWVazSwbwgl/EACiWYbRauHDUQA9f+Rq+ayWcsR" +
"os1CD+Q81y9SmlQaZVKkSPZLxXfu5bi3s4o431xjilhZdt4vKbj2pK364IjghJPNBBfmRXzlj9awKxr/" +
"UebZcBgNRyeky7VZSbbF2jQSQ==";
String encryptedString = RSAHelper.encryptWithSSHPublicKey(dssKey, "content");
assertNull(encryptedString);
}
}

View File

@ -0,0 +1,69 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.utils.ssh;
import static org.junit.Assert.*;
import org.junit.Test;
public class SSHKeysHelperTest {
@Test
public void rsaKeyTest() {
String rsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2D2Cs0XAEqm+ajJpumIPrMpKp0CWtIW+8ZY2/MJCW" +
"hge1eY18u9I3PPnkMVJsTOaN0wQojjw4AkKgKjNZXA9wyUq56UyN/stmipu8zifWPgxQGDRkuzzZ6buk" +
"ef8q2Awjpo8hv5/0SRPJxQLEafESnUP+Uu/LUwk5VVC7PHzywJRUGFuzDl/uT72+6hqpL2YpC6aTl4/P" +
"2eDvUQhCdL9dBmUSFX8ftT53W1jhsaQl7mPElVgSCtWz3IyRkogobMPrpJW/IPKEiojKIuvNoNv4CDR6" +
"ybeVjHOJMb9wi62rXo+CzUsW0Y4jPOX/OykAm5vrNOhQhw0aaBcv5XVv8BRX test@testkey";
String storedRsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2D2Cs0XAEqm+ajJpumIPrMpKp0CWtIW+8ZY2/MJCW" +
"hge1eY18u9I3PPnkMVJsTOaN0wQojjw4AkKgKjNZXA9wyUq56UyN/stmipu8zifWPgxQGDRkuzzZ6buk" +
"ef8q2Awjpo8hv5/0SRPJxQLEafESnUP+Uu/LUwk5VVC7PHzywJRUGFuzDl/uT72+6hqpL2YpC6aTl4/P" +
"2eDvUQhCdL9dBmUSFX8ftT53W1jhsaQl7mPElVgSCtWz3IyRkogobMPrpJW/IPKEiojKIuvNoNv4CDR6" +
"ybeVjHOJMb9wi62rXo+CzUsW0Y4jPOX/OykAm5vrNOhQhw0aaBcv5XVv8BRX";
String parsedKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(rsaKey);
String fingerprint = SSHKeysHelper.getPublicKeyFingerprint(parsedKey);
assertTrue(storedRsaKey.equals(parsedKey));
assertTrue("f6:96:3f:f4:78:f7:80:11:6c:f8:e3:2b:40:20:f1:14".equals(fingerprint));
}
@Test
public void dsaKeyTest() {
String dssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBALbaewDnzZ5AcGbZno7VW1m7Si3Q+yEANXZioVupfSwOP0q9aP2iV"+
"tyqq575JnUVZXMDR2Gr254F/qCJ0TKAvucN0gcd2XslX4jBcu1Z7s7YZf6d7fC58k0NE6/keokJNKhQO" +
"i56iirRzSA/YFrD64mzfq6rEmai0q7GjGGP0RT1AAAAFQDO5++6JonyqnoRkV9Yl1OaEOPjVwAAAIAYA" +
"tqtKtU/INlTIuL3wt3nyKzwPUnz3fqxP5Ger3OlRZsOahalTFt2OF5jGGmCunyBTRteOetZObr0QhUIF" +
"4bSDr6UiYYYbH1ES0ws/t1mDIeTh3UUHV1QYACN6c07FKyKLMtB9AthiG2FMLKCEedG3NeXItuNzsuQD" +
"+n/K1rzMAAAAIBi5SM4pFPiB7BvTZvARV56vrG5QNgWVazSwbwgl/EACiWYbRauHDUQA9f+Rq+ayWcsR" +
"os1CD+Q81y9SmlQaZVKkSPZLxXfu5bi3s4o431xjilhZdt4vKbj2pK364IjghJPNBBfmRXzlj9awKxr/" +
"UebZcBgNRyeky7VZSbbF2jQSQ== test key";
String storedDssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBALbaewDnzZ5AcGbZno7VW1m7Si3Q+yEANXZioVupfSwOP0q9aP2iV"+
"tyqq575JnUVZXMDR2Gr254F/qCJ0TKAvucN0gcd2XslX4jBcu1Z7s7YZf6d7fC58k0NE6/keokJNKhQO" +
"i56iirRzSA/YFrD64mzfq6rEmai0q7GjGGP0RT1AAAAFQDO5++6JonyqnoRkV9Yl1OaEOPjVwAAAIAYA" +
"tqtKtU/INlTIuL3wt3nyKzwPUnz3fqxP5Ger3OlRZsOahalTFt2OF5jGGmCunyBTRteOetZObr0QhUIF" +
"4bSDr6UiYYYbH1ES0ws/t1mDIeTh3UUHV1QYACN6c07FKyKLMtB9AthiG2FMLKCEedG3NeXItuNzsuQD" +
"+n/K1rzMAAAAIBi5SM4pFPiB7BvTZvARV56vrG5QNgWVazSwbwgl/EACiWYbRauHDUQA9f+Rq+ayWcsR" +
"os1CD+Q81y9SmlQaZVKkSPZLxXfu5bi3s4o431xjilhZdt4vKbj2pK364IjghJPNBBfmRXzlj9awKxr/" +
"UebZcBgNRyeky7VZSbbF2jQSQ==";
String parsedKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(dssKey);
String fingerprint = SSHKeysHelper.getPublicKeyFingerprint(parsedKey);
assertTrue(storedDssKey.equals(parsedKey));
assertTrue("fc:6e:ef:31:93:f8:92:2b:a9:03:c7:06:90:f5:ec:bb".equals(fingerprint));
}
}