/// <summary> /// constructs from file /// </summary> /// <param name="path">file name</param> /// <param name="passphrase">passphrase or empty string if passphrase is not required</param> public SSH1UserAuthKey(string path, string passphrase) { var fileTask = StorageFile.GetFileFromPathAsync(path); fileTask.AsTask().Wait(); var fileObject = fileTask.AsTask().Result; var openTask = fileObject.OpenReadAsync(); openTask.AsTask().Wait(); Stream s = openTask.AsTask().Result.AsStream(); byte[] header = new byte[32]; s.Read(header, 0, header.Length); if (Encoding.UTF8.GetString(header, 0, header.Length) != "SSH PRIVATE KEY FILE FORMAT 1.1\n") { //throw new Exception(String.Format(Strings.GetString("BrokenKeyFile"), path)); throw new Exception(String.Format(Strings.GetString("BrokenKeyFile"), path)); } SSH1DataReader reader = new SSH1DataReader(ReadAll(s)); s.Dispose(); byte[] cipher = reader.Read(2); //first 2 bytes indicates algorithm and next 8 bytes is space reader.Read(8); _modulus = reader.ReadMPInt(); _publicExponent = reader.ReadMPInt(); byte[] comment = reader.ReadString(); byte[] prvt = reader.ReadAll(); //必要なら復号 CipherAlgorithm algo = (CipherAlgorithm)cipher[1]; if (algo != 0) { Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH1, algo, ConvertToKey(passphrase)); byte[] buf = new byte[prvt.Length]; c.Decrypt(prvt, 0, prvt.Length, buf, 0); prvt = buf; } SSH1DataReader prvtreader = new SSH1DataReader(prvt); byte[] mark = prvtreader.Read(4); if (mark[0] != mark[2] || mark[1] != mark[3]) { //throw new Exception(Strings.GetString("WrongPassphrase")); throw new Exception(Strings.GetString("WrongPassphrase")); } _privateExponent = prvtreader.ReadMPInt(); _crtCoefficient = prvtreader.ReadMPInt(); _primeP = prvtreader.ReadMPInt(); _primeQ = prvtreader.ReadMPInt(); }
/// <summary> /// constructs from file /// </summary> /// <param name="path">file name</param> /// <param name="passphrase">passphrase or empty string if passphrase is not required</param> public SSH1UserAuthKey(string path, string passphrase) { var fileTask = StorageFile.GetFileFromPathAsync(path); fileTask.AsTask().Wait(); var fileObject = fileTask.AsTask().Result; var openTask = fileObject.OpenReadAsync(); openTask.AsTask().Wait(); Stream s = openTask.AsTask().Result.AsStream(); byte[] header = new byte[32]; s.Read(header, 0, header.Length); if(Encoding.UTF8.GetString(header,0,header.Length)!="SSH PRIVATE KEY FILE FORMAT 1.1\n") //throw new Exception(String.Format(Strings.GetString("BrokenKeyFile"), path)); throw new Exception(String.Format(Strings.GetString("BrokenKeyFile"), path)); SSH1DataReader reader = new SSH1DataReader(ReadAll(s)); s.Dispose(); byte[] cipher = reader.Read(2); //first 2 bytes indicates algorithm and next 8 bytes is space reader.Read(8); _modulus = reader.ReadMPInt(); _publicExponent = reader.ReadMPInt(); byte[] comment = reader.ReadString(); byte[] prvt = reader.ReadAll(); //�K�v�Ȃ畜�� CipherAlgorithm algo = (CipherAlgorithm)cipher[1]; if(algo!=0) { Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH1, algo, ConvertToKey(passphrase)); byte[] buf = new byte[prvt.Length]; c.Decrypt(prvt, 0, prvt.Length, buf, 0); prvt = buf; } SSH1DataReader prvtreader = new SSH1DataReader(prvt); byte[] mark = prvtreader.Read(4); if(mark[0]!=mark[2] || mark[1]!=mark[3]) //throw new Exception(Strings.GetString("WrongPassphrase")); throw new Exception(Strings.GetString("WrongPassphrase")); _privateExponent = prvtreader.ReadMPInt(); _crtCoefficient = prvtreader.ReadMPInt(); _primeP = prvtreader.ReadMPInt(); _primeQ = prvtreader.ReadMPInt(); }
//RSA authentication private void DoRSAChallengeResponse() { //read key SSH1UserAuthKey key = new SSH1UserAuthKey(_param.IdentityFile, _param.Password); SSH1DataWriter w = new SSH1DataWriter(); w.Write(key.PublicModulus); SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_AUTH_RSA, w.ToByteArray()); p.WriteTo(_stream, _tCipher); p = ReceivePacket(); if (p.Type == PacketType.SSH_SMSG_FAILURE) { throw new Exception(Strings.GetString("ServerRefusedRSA")); } else if (p.Type != PacketType.SSH_SMSG_AUTH_RSA_CHALLENGE) { throw new Exception(String.Format(Strings.GetString("UnexpectedResponse"), p.Type)); } //creating challenge SSH1DataReader r = new SSH1DataReader(p.Data); BigInteger challenge = key.decryptChallenge(r.ReadMPInt()); byte[] rawchallenge = RSAUtil.StripPKCS1Pad(challenge, 2).getBytes(); //building response MemoryStream bos = new MemoryStream(); bos.Write(rawchallenge, 0, rawchallenge.Length); //!!mindtermでは頭が0かどうかで変なハンドリングがあった bos.Write(_sessionID, 0, _sessionID.Length); byte[] response = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5).HashData(bos.ToArray().AsBuffer()).ToArray();; w = new SSH1DataWriter(); w.Write(response); p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_AUTH_RSA_RESPONSE, w.ToByteArray()); p.WriteTo(_stream, _tCipher); }
//RSA authentication private void DoRSAChallengeResponse() { //read key SSH1UserAuthKey key = new SSH1UserAuthKey(_param.IdentityFile, _param.Password); SSH1DataWriter w = new SSH1DataWriter(); w.Write(key.PublicModulus); SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_AUTH_RSA, w.ToByteArray()); p.WriteTo(_stream, _tCipher); p = ReceivePacket(); if(p.Type==PacketType.SSH_SMSG_FAILURE) throw new Exception(Strings.GetString("ServerRefusedRSA")); else if(p.Type!=PacketType.SSH_SMSG_AUTH_RSA_CHALLENGE) throw new Exception(String.Format(Strings.GetString("UnexpectedResponse"), p.Type)); //creating challenge SSH1DataReader r = new SSH1DataReader(p.Data); BigInteger challenge = key.decryptChallenge(r.ReadMPInt()); byte[] rawchallenge = RSAUtil.StripPKCS1Pad(challenge, 2).getBytes(); //building response MemoryStream bos = new MemoryStream(); bos.Write(rawchallenge, 0, rawchallenge.Length); //!!mindterm�ł͓����O���ǂ����ŕςȃn���h�����O�������� bos.Write(_sessionID, 0, _sessionID.Length); byte[] response = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5).HashData(bos.ToArray().AsBuffer()).ToArray(); ; w = new SSH1DataWriter(); w.Write(response); p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_AUTH_RSA_RESPONSE, w.ToByteArray()); p.WriteTo(_stream, _tCipher); }