private static int GetIntegerSize(SSH2DataReader binr) { byte bt = 0; byte lowbyte = 0x00; byte highbyte = 0x00; int count = 0; bt = binr.ReadByte(); if (bt != 0x02) //expect integer { return(0); } bt = binr.ReadByte(); if (bt == 0x81) { count = binr.ReadByte(); // data size in next byte } else if (bt == 0x82) { highbyte = binr.ReadByte(); // data size in next 2 bytes lowbyte = binr.ReadByte(); byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; count = BitConverter.ToInt32(modint, 0); } else { count = bt; // we already have the data size } while (binr.ReadByte() == 0x00) { //remove high order zeros in data count -= 1; } binr.Seek(-1); //last ReadByte wasn't a removed zero, so back up a byte return(count); }
private static int GetIntegerSize(SSH2DataReader binr) { byte bt = 0; byte lowbyte = 0x00; byte highbyte = 0x00; int count = 0; bt = binr.ReadByte(); if (bt != 0x02) //expect integer return 0; bt = binr.ReadByte(); if (bt == 0x81) count = binr.ReadByte(); // data size in next byte else if (bt == 0x82) { highbyte = binr.ReadByte(); // data size in next 2 bytes lowbyte = binr.ReadByte(); byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; count = BitConverter.ToInt32(modint, 0); } else { count = bt; // we already have the data size } while (binr.ReadByte() == 0x00) { //remove high order zeros in data count -= 1; } binr.Seek(-1); //last ReadByte wasn't a removed zero, so back up a byte return count; }
/* * Format style note * ---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- * Comment: ******* * <base64-encoded body> * ---- END SSH2 ENCRYPTED PRIVATE KEY ---- * * body = MAGIC_VAL || body-length || type(string) || encryption-algorithm-name(string) || encrypted-body(string) * encrypted-body = array of BigInteger(algorithm-specific) */ internal static SSH2UserAuthKey FromRSAOpenSSHStyleStream(StreamReader r, string passphrase) { string l = r.ReadLine(); StringBuilder buf = new StringBuilder(); while (l != "-----END RSA PRIVATE KEY-----") { if (l.IndexOf(':') == -1) buf.Append(l); else { while (l.EndsWith("\\")) l = r.ReadLine(); } l = r.ReadLine(); if (l == null) throw new Exception(resLoader.GetString("BrokenKeyFile")); } //r.Close(); byte[] keydata = CryptographicBuffer.DecodeFromBase64String(buf.ToString()).ToArray(); if (passphrase != "") { r.BaseStream.Seek(0, SeekOrigin.Begin); r.ReadLine();//Get rid of header if (!r.ReadLine().StartsWith("Proc-Type: 4,ENCRYPTED")) throw new Exception(resLoader.GetString("KeyFormatUnsupported")); String saltline = r.ReadLine(); if (!saltline.StartsWith("DEK-Info: DES-EDE3-CBC,")) throw new Exception(resLoader.GetString("KeyFormatUnsupported")); String saltstr = saltline.Substring(saltline.IndexOf(",") + 1).Trim(); byte[] salt = new byte[saltstr.Length / 2]; for (int i = 0; i < salt.Length; i++) salt[i] = Convert.ToByte(saltstr.Substring(i * 2, 2), 16); byte[] deskey = GetOpenSSL3deskey(salt, passphrase, 1, 2); if (deskey == null) return null; byte[] rsakey = DecryptKey(keydata, deskey, salt); keydata = rsakey; } r.Dispose(); SSH2DataReader re = new SSH2DataReader(keydata); int magic = re.ReadInt16(); if (magic != OPEN_SSH_MAGIC_VAL) throw new Exception(resLoader.GetString("BrokenKeyFile")); int length = re.ReadInt16(); //Version re.ReadByte(); // tag: 2 re.ReadByte(); // stored length: 1 int version = (int)re.ReadByte(); // 0 //Modulus length = GetIntegerSize(re); // tag: 2 BigInteger n = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger e = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger d = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger p = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger q = new BigInteger(re.Read(length)); //u ?? is not stored? calculated in special constructor /* length = GetIntegerSize(re); // tag: 2 BigInteger u = re.ReadASNBigInt(); */ return new SSH2UserAuthKey(new RSAKeyPair(n, e, d, p, q)); }
/* * Format style note * ---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- * Comment: ******* * <base64-encoded body> * ---- END SSH2 ENCRYPTED PRIVATE KEY ---- * * body = MAGIC_VAL || body-length || type(string) || encryption-algorithm-name(string) || encrypted-body(string) * encrypted-body = array of BigInteger(algorithm-specific) */ internal static SSH2UserAuthKey FromRSAOpenSSHStyleStream(StreamReader r, string passphrase) { string l = r.ReadLine(); StringBuilder buf = new StringBuilder(); while (l != "-----END RSA PRIVATE KEY-----") { if (l.IndexOf(':') == -1) { buf.Append(l); } else { while (l.EndsWith("\\")) { l = r.ReadLine(); } } l = r.ReadLine(); if (l == null) { throw new Exception(resLoader.GetString("BrokenKeyFile")); } } //r.Close(); byte[] keydata = CryptographicBuffer.DecodeFromBase64String(buf.ToString()).ToArray(); if (passphrase != "") { r.BaseStream.Seek(0, SeekOrigin.Begin); r.ReadLine();//Get rid of header if (!r.ReadLine().StartsWith("Proc-Type: 4,ENCRYPTED")) { throw new Exception(resLoader.GetString("KeyFormatUnsupported")); } String saltline = r.ReadLine(); if (!saltline.StartsWith("DEK-Info: DES-EDE3-CBC,")) { throw new Exception(resLoader.GetString("KeyFormatUnsupported")); } String saltstr = saltline.Substring(saltline.IndexOf(",") + 1).Trim(); byte[] salt = new byte[saltstr.Length / 2]; for (int i = 0; i < salt.Length; i++) { salt[i] = Convert.ToByte(saltstr.Substring(i * 2, 2), 16); } byte[] deskey = GetOpenSSL3deskey(salt, passphrase, 1, 2); if (deskey == null) { return(null); } byte[] rsakey = DecryptKey(keydata, deskey, salt); keydata = rsakey; } r.Dispose(); SSH2DataReader re = new SSH2DataReader(keydata); int magic = re.ReadInt16(); if (magic != OPEN_SSH_MAGIC_VAL) { throw new Exception(resLoader.GetString("BrokenKeyFile")); } int length = re.ReadInt16(); //Version re.ReadByte(); // tag: 2 re.ReadByte(); // stored length: 1 int version = (int)re.ReadByte(); // 0 //Modulus length = GetIntegerSize(re); // tag: 2 BigInteger n = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger e = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger d = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger p = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger q = new BigInteger(re.Read(length)); //u ?? is not stored? calculated in special constructor /* * length = GetIntegerSize(re); // tag: 2 * BigInteger u = re.ReadASNBigInt(); */ return(new SSH2UserAuthKey(new RSAKeyPair(n, e, d, p, q))); }