public void TestAddBigInt() { BlobBuilder builder = new BlobBuilder(); BigInteger value = new BigInteger("12398259028592293582039293420948023"); builder.AddBigIntBlob(value); byte[] valueBytes = value.ToByteArrayUnsigned(); //Assert.That(valueBytes[0], Is.EqualTo(0)); byte[] expected = new byte[valueBytes.Length + 4]; Array.Copy(valueBytes.Length.ToBytes(), expected, 4); Array.Copy(valueBytes, 0, expected, 4, valueBytes.Length); Assert.That(builder.GetBlob(), Is.EqualTo(expected)); }
/// <summary> /// reads OpenSSH formatted public key blob and creates /// an AsymmetricKeyParameter object /// </summary> /// <returns>AsymmetricKeyParameter containing the public key</returns> public AsymmetricKeyParameter ReadSsh2PublicKeyData(out OpensshCertificate cert) { cert = null; var algorithm = Encoding.UTF8.GetString(ReadBlob()); var certBuilder = new BlobBuilder(); certBuilder.AddStringBlob(algorithm); switch (algorithm) { case PublicKeyAlgorithmExt.ALGORITHM_RSA_KEY: { var n = new BigInteger(1, ReadBlob()); // modulus var e = new BigInteger(1, ReadBlob()); // exponent if (n.BitLength < e.BitLength) { // In some cases, the modulus is first. We can always tell because // it is significantly larget than the exponent. return(new RsaKeyParameters(false, e, n)); } return(new RsaKeyParameters(false, n, e)); } case PublicKeyAlgorithmExt.ALGORITHM_RSA_CERT_V1: { var nonce = ReadBlob(); if (nonce.Length != 32) { // we are being called from SSH2_AGENTC_ADD_IDENTITY and this blob // is the whole certificate, not the nonce var certParser = new BlobParser(nonce); return(certParser.ReadSsh2PublicKeyData(out cert)); } else { certBuilder.AddBlob(nonce); var e = new BigInteger(1, ReadBlob()); certBuilder.AddBigIntBlob(e); var n = new BigInteger(1, ReadBlob()); certBuilder.AddBigIntBlob(n); cert = ReadCertificate(certBuilder); return(new RsaKeyParameters(false, n, e)); } } case PublicKeyAlgorithmExt.ALGORITHM_DSA_KEY: { var p = new BigInteger(1, ReadBlob()); var q = new BigInteger(1, ReadBlob()); var g = new BigInteger(1, ReadBlob()); var y = new BigInteger(1, ReadBlob()); var dsaParams = new DsaParameters(p, q, g); return(new DsaPublicKeyParameters(y, dsaParams)); } case PublicKeyAlgorithmExt.ALGORITHM_DSA_CERT_V1: { var nonce = ReadBlob(); if (nonce.Length != 32) { // we are being called from SSH2_AGENTC_ADD_IDENTITY and this blob // is the whole certificate, not the nonce var certParser = new BlobParser(nonce); return(certParser.ReadSsh2PublicKeyData(out cert)); } else { certBuilder.AddBlob(nonce); var p = new BigInteger(1, ReadBlob()); certBuilder.AddBigIntBlob(p); var q = new BigInteger(1, ReadBlob()); certBuilder.AddBigIntBlob(q); var g = new BigInteger(1, ReadBlob()); certBuilder.AddBigIntBlob(g); var y = new BigInteger(1, ReadBlob()); certBuilder.AddBigIntBlob(y); cert = ReadCertificate(certBuilder); var dsaParams = new DsaParameters(p, q, g); return(new DsaPublicKeyParameters(y, dsaParams)); } } case PublicKeyAlgorithmExt.ALGORITHM_ECDSA_SHA2_NISTP256_KEY: case PublicKeyAlgorithmExt.ALGORITHM_ECDSA_SHA2_NISTP384_KEY: case PublicKeyAlgorithmExt.ALGORITHM_ECDSA_SHA2_NISTP521_KEY: { var curveName = ReadString(); var publicKey = ReadBlob(); var x9Params = SecNamedCurves.GetByName(EcCurveToAlgorithm(curveName)); var domainParams = new ECDomainParameters(x9Params.Curve, x9Params.G, x9Params.N, x9Params.H); var point = x9Params.Curve.DecodePoint(publicKey); return(new ECPublicKeyParameters(point, domainParams)); } case PublicKeyAlgorithmExt.ALGORITHM_ECDSA_SHA2_NISTP256_CERT_V1: case PublicKeyAlgorithmExt.ALGORITHM_ECDSA_SHA2_NISTP384_CERT_V1: case PublicKeyAlgorithmExt.ALGORITHM_ECDSA_SHA2_NISTP521_CERT_V1: { var nonce = ReadBlob(); if (nonce.Length != 32) { // we are being called from SSH2_AGENTC_ADD_IDENTITY and this blob // is the whole certificate, not the nonce var certParser = new BlobParser(nonce); return(certParser.ReadSsh2PublicKeyData(out cert)); } else { certBuilder.AddBlob(nonce); var curveName = ReadString(); certBuilder.AddStringBlob(curveName); var publicKey = ReadBlob(); certBuilder.AddBlob(publicKey); cert = ReadCertificate(certBuilder); var x9Params = SecNamedCurves.GetByName(EcCurveToAlgorithm(curveName)); var domainParams = new ECDomainParameters(x9Params.Curve, x9Params.G, x9Params.N, x9Params.H); var point = x9Params.Curve.DecodePoint(publicKey); return(new ECPublicKeyParameters(point, domainParams)); } } case PublicKeyAlgorithmExt.ALGORITHM_ED25519: { var publicKey = ReadBlob(); return(new Ed25519PublicKeyParameter(publicKey)); } case PublicKeyAlgorithmExt.ALGORITHM_ED25519_CERT_V1: { var nonce = ReadBlob(); if (nonce.Length != 32) { // we are being called from SSH2_AGENTC_ADD_IDENTITY and this blob // is the whole certificate, not the nonce var certParser = new BlobParser(nonce); certParser.ReadSsh2PublicKeyData(out cert); var publicKey = ReadBlob(); return(new Ed25519PublicKeyParameter(publicKey)); } else { certBuilder.AddBlob(nonce); var publicKey = ReadBlob(); certBuilder.AddBlob(publicKey); cert = ReadCertificate(certBuilder); return(new Ed25519PublicKeyParameter(publicKey)); } } default: // unsupported encryption algorithm throw new Exception("Unsupported algorithm"); } }
/// <summary> /// Gets OpenSsh formatted bytes from public key /// </summary> /// <param name="key">The key.</param> /// <param name="cert">When set to <c>true</c> and the key has a certificate, the certificate blob will be used.</param> /// <returns>byte array containing key information</returns> public static byte[] GetPublicKeyBlob(this ISshKey key, bool cert = true) { if (cert && key.Certificate != null) { return(key.Certificate.Blob); } AsymmetricKeyParameter parameters = key.GetPublicKeyParameters(); BlobBuilder builder = new BlobBuilder(); if (parameters is RsaKeyParameters) { RsaKeyParameters rsaPublicKeyParameters = (RsaKeyParameters)parameters; if (key.Version == SshVersion.SSH1) { builder.AddInt(key.Size); builder.AddSsh1BigIntBlob(rsaPublicKeyParameters.Exponent); builder.AddSsh1BigIntBlob(rsaPublicKeyParameters.Modulus); } else { builder.AddStringBlob(PublicKeyAlgorithm.SSH_RSA.GetIdentifierString()); builder.AddBigIntBlob(rsaPublicKeyParameters.Exponent); builder.AddBigIntBlob(rsaPublicKeyParameters.Modulus); } } else if (parameters is DsaPublicKeyParameters) { DsaPublicKeyParameters dsaParameters = (DsaPublicKeyParameters)parameters; builder.AddStringBlob(PublicKeyAlgorithm.SSH_DSS.GetIdentifierString()); builder.AddBigIntBlob(dsaParameters.Parameters.P); builder.AddBigIntBlob(dsaParameters.Parameters.Q); builder.AddBigIntBlob(dsaParameters.Parameters.G); builder.AddBigIntBlob(dsaParameters.Y); } else if (parameters is ECPublicKeyParameters) { ECPublicKeyParameters ecdsaParameters = (ECPublicKeyParameters)parameters; string algorithm; switch (ecdsaParameters.Parameters.Curve.FieldSize) { case 256: algorithm = PublicKeyAlgorithm.ECDSA_SHA2_NISTP256.GetIdentifierString(); break; case 384: algorithm = PublicKeyAlgorithm.ECDSA_SHA2_NISTP384.GetIdentifierString(); break; case 521: algorithm = PublicKeyAlgorithm.ECDSA_SHA2_NISTP521.GetIdentifierString(); break; default: throw new ArgumentException("Unsupported EC size: " + ecdsaParameters.Parameters.Curve.FieldSize); } builder.AddStringBlob(algorithm); algorithm = algorithm.Replace(PublicKeyAlgorithmExt.ALGORITHM_ECDSA_SHA2_PREFIX, string.Empty); builder.AddStringBlob(algorithm); builder.AddBlob(ecdsaParameters.Q.GetEncoded()); } else if (parameters is Ed25519PublicKeyParameter) { builder.AddStringBlob(PublicKeyAlgorithm.ED25519.GetIdentifierString()); builder.AddBlob(((Ed25519PublicKeyParameter)parameters).Key); } else { throw new ArgumentException(parameters.GetType() + " is not supported"); } byte[] result = builder.GetBlob(); builder.Clear(); return(result); }
BlobBuilder CreatePrivateKeyBlob(ISshKey key) { var builder = new BlobBuilder(); switch (key.Version) { case SshVersion.SSH1: var privateKeyParams = key.GetPrivateKeyParameters() as RsaPrivateCrtKeyParameters; builder.AddInt(key.Size); builder.AddSsh1BigIntBlob(privateKeyParams.Modulus); builder.AddSsh1BigIntBlob(privateKeyParams.PublicExponent); builder.AddSsh1BigIntBlob(privateKeyParams.Exponent); builder.AddSsh1BigIntBlob(privateKeyParams.QInv); builder.AddSsh1BigIntBlob(privateKeyParams.Q); builder.AddSsh1BigIntBlob(privateKeyParams.P); break; case SshVersion.SSH2: builder.AddStringBlob(key.Algorithm.GetIdentifierString()); switch (key.Algorithm) { case PublicKeyAlgorithm.SSH_DSS: var dsaPublicKeyParameters = key.GetPublicKeyParameters() as DsaPublicKeyParameters; var dsaPrivateKeyParamters = key.GetPrivateKeyParameters() as DsaPrivateKeyParameters; builder.AddBigIntBlob(dsaPublicKeyParameters.Parameters.P); builder.AddBigIntBlob(dsaPublicKeyParameters.Parameters.Q); builder.AddBigIntBlob(dsaPublicKeyParameters.Parameters.G); builder.AddBigIntBlob(dsaPublicKeyParameters.Y); builder.AddBigIntBlob(dsaPrivateKeyParamters.X); break; case PublicKeyAlgorithm.ECDSA_SHA2_NISTP256: case PublicKeyAlgorithm.ECDSA_SHA2_NISTP384: case PublicKeyAlgorithm.ECDSA_SHA2_NISTP521: var ecdsaPublicKeyParameters = key.GetPublicKeyParameters() as ECPublicKeyParameters; var ecdsaPrivateKeyParameters = key.GetPrivateKeyParameters() as ECPrivateKeyParameters; builder.AddStringBlob(key.Algorithm.GetIdentifierString() .Replace(PublicKeyAlgorithmExt.ALGORITHM_ECDSA_SHA2_PREFIX, string.Empty)); builder.AddBlob(ecdsaPublicKeyParameters.Q.GetEncoded()); builder.AddBigIntBlob(ecdsaPrivateKeyParameters.D); break; case PublicKeyAlgorithm.SSH_RSA: var rsaPrivateKeyParameters = key.GetPrivateKeyParameters() as RsaPrivateCrtKeyParameters; builder.AddBigIntBlob(rsaPrivateKeyParameters.Modulus); builder.AddBigIntBlob(rsaPrivateKeyParameters.PublicExponent); builder.AddBigIntBlob(rsaPrivateKeyParameters.Exponent); builder.AddBigIntBlob(rsaPrivateKeyParameters.QInv); builder.AddBigIntBlob(rsaPrivateKeyParameters.P); builder.AddBigIntBlob(rsaPrivateKeyParameters.Q); break; case PublicKeyAlgorithm.ED25519: var ed25519PublicKeyParameters = key.GetPublicKeyParameters() as Ed25519PublicKeyParameter; var ed25519PrivateKeyParameters = key.GetPrivateKeyParameters() as Ed25519PrivateKeyParameter; builder.AddBlob(ed25519PublicKeyParameters.Key); builder.AddBlob(ed25519PrivateKeyParameters.Signature); break; default: throw new Exception("Unsupported algorithm"); } break; default: throw new Exception(cUnsupportedSshVersion); } builder.AddStringBlob(key.Comment); return(builder); }
/// <summary> /// Gets OpenSsh formatted bytes from public key /// </summary> /// <param name="Algorithm">AsymmetricAlgorithm to convert.</param> /// <returns>byte array containing key information</returns> /// <exception cref="ArgumentException"> /// AsymmetricAlgorithm is not supported /// </exception> /// <remarks> /// Currently only supports RSA and DSA public keys /// </remarks> public static byte[] GetPublicKeyBlob(this ISshKey aKey) { AsymmetricKeyParameter parameters = aKey.GetPublicKeyParameters(); BlobBuilder builder = new BlobBuilder(); if (parameters is RsaKeyParameters) { RsaKeyParameters rsaPublicKeyParameters = (RsaKeyParameters)parameters; if (aKey.Version == SshVersion.SSH1) { builder.AddInt(aKey.Size); builder.AddSsh1BigIntBlob(rsaPublicKeyParameters.Exponent); builder.AddSsh1BigIntBlob(rsaPublicKeyParameters.Modulus); } else { builder.AddStringBlob(PublicKeyAlgorithm.SSH_RSA.GetIdentifierString()); builder.AddBigIntBlob(rsaPublicKeyParameters.Exponent); builder.AddBigIntBlob(rsaPublicKeyParameters.Modulus); } } else if (parameters is DsaPublicKeyParameters) { DsaPublicKeyParameters dsaParameters = (DsaPublicKeyParameters)parameters; builder.AddStringBlob(PublicKeyAlgorithm.SSH_DSS.GetIdentifierString()); builder.AddBigIntBlob(dsaParameters.Parameters.P); builder.AddBigIntBlob(dsaParameters.Parameters.Q); builder.AddBigIntBlob(dsaParameters.Parameters.G); builder.AddBigIntBlob(dsaParameters.Y); } else if (parameters is ECPublicKeyParameters) { ECPublicKeyParameters ecdsaParameters = (ECPublicKeyParameters)parameters; string algorithm; switch (ecdsaParameters.Parameters.Curve.FieldSize) { case 256: algorithm = PublicKeyAlgorithm.ECDSA_SHA2_NISTP256.GetIdentifierString(); break; case 384: algorithm = PublicKeyAlgorithm.ECDSA_SHA2_NISTP384.GetIdentifierString(); break; case 521: algorithm = PublicKeyAlgorithm.ECDSA_SHA2_NISTP521.GetIdentifierString(); break; default: throw new ArgumentException("Unsupported EC size: " + ecdsaParameters.Parameters.Curve.FieldSize); } builder.AddStringBlob(algorithm); algorithm = algorithm.Replace(PublicKeyAlgorithmExt.ALGORITHM_ECDSA_SHA2_PREFIX, string.Empty); builder.AddStringBlob(algorithm); builder.AddBlob(ecdsaParameters.Q.GetEncoded()); } else if (parameters is Ed25519PublicKeyParameter) { builder.AddStringBlob(PublicKeyAlgorithm.ED25519.GetIdentifierString()); builder.AddBlob(((Ed25519PublicKeyParameter)parameters).Key); } else { throw new ArgumentException(parameters.GetType() + " is not supported"); } byte[] result = builder.GetBlob(); builder.Clear(); return result; }
BlobBuilder CreatePrivateKeyBlob(ISshKey key) { var builder = new BlobBuilder(); switch (key.Version) { case SshVersion.SSH1: var privateKeyParams = key.GetPrivateKeyParameters() as RsaPrivateCrtKeyParameters; builder.AddInt(key.Size); builder.AddSsh1BigIntBlob(privateKeyParams.Modulus); builder.AddSsh1BigIntBlob(privateKeyParams.PublicExponent); builder.AddSsh1BigIntBlob(privateKeyParams.Exponent); builder.AddSsh1BigIntBlob(privateKeyParams.QInv); builder.AddSsh1BigIntBlob(privateKeyParams.Q); builder.AddSsh1BigIntBlob(privateKeyParams.P); break; case SshVersion.SSH2: builder.AddStringBlob(key.Algorithm.GetIdentifierString()); switch (key.Algorithm) { case PublicKeyAlgorithm.SSH_DSS: var dsaPublicKeyParameters = key.GetPublicKeyParameters() as DsaPublicKeyParameters; var dsaPrivateKeyParamters = key.GetPrivateKeyParameters() as DsaPrivateKeyParameters; builder.AddBigIntBlob(dsaPublicKeyParameters.Parameters.P); builder.AddBigIntBlob(dsaPublicKeyParameters.Parameters.Q); builder.AddBigIntBlob(dsaPublicKeyParameters.Parameters.G); builder.AddBigIntBlob(dsaPublicKeyParameters.Y); builder.AddBigIntBlob(dsaPrivateKeyParamters.X); break; case PublicKeyAlgorithm.ECDSA_SHA2_NISTP256: case PublicKeyAlgorithm.ECDSA_SHA2_NISTP384: case PublicKeyAlgorithm.ECDSA_SHA2_NISTP521: var ecdsaPublicKeyParameters = key.GetPublicKeyParameters() as ECPublicKeyParameters; var ecdsaPrivateKeyParameters = key.GetPrivateKeyParameters() as ECPrivateKeyParameters; builder.AddStringBlob(key.Algorithm.GetIdentifierString() .Replace(PublicKeyAlgorithmExt.ALGORITHM_ECDSA_SHA2_PREFIX, string.Empty)); builder.AddBlob(ecdsaPublicKeyParameters.Q.GetEncoded()); builder.AddBigIntBlob(ecdsaPrivateKeyParameters.D); break; case PublicKeyAlgorithm.SSH_RSA: var rsaPrivateKeyParameters = key.GetPrivateKeyParameters() as RsaPrivateCrtKeyParameters; builder.AddBigIntBlob(rsaPrivateKeyParameters.Modulus); builder.AddBigIntBlob(rsaPrivateKeyParameters.PublicExponent); builder.AddBigIntBlob(rsaPrivateKeyParameters.Exponent); builder.AddBigIntBlob(rsaPrivateKeyParameters.QInv); builder.AddBigIntBlob(rsaPrivateKeyParameters.P); builder.AddBigIntBlob(rsaPrivateKeyParameters.Q); break; case PublicKeyAlgorithm.ED25519: var ed25519PublicKeyParameters = key.GetPublicKeyParameters() as Ed25519PublicKeyParameter; var ed25519PrivateKeyParameters = key.GetPrivateKeyParameters() as Ed25519PrivateKeyParameter; builder.AddBlob(ed25519PublicKeyParameters.Key); builder.AddBlob(ed25519PrivateKeyParameters.Signature); break; default: throw new Exception("Unsupported algorithm"); } break; default: throw new Exception(cUnsupportedSshVersion); } builder.AddStringBlob(key.Comment); return builder; }
public void TestAnswerSSH2_AGENTC_ADD_ID_CONSTRAINED() { /* most code is shared with SSH2_AGENTC_ADD_IDENTITY, so we just * need to test the differences */ Agent.ConfirmUserPermissionDelegate confirmCallback = delegate(ISshKey k, Process p) { return true; }; Agent agent = new TestAgent(); /* test that no confirmation callback returns failure */ BlobBuilder builder = new BlobBuilder(); RsaPrivateCrtKeyParameters rsaParameters = (RsaPrivateCrtKeyParameters)rsaKey.GetPrivateKeyParameters(); builder.AddStringBlob(rsaKey.Algorithm.GetIdentifierString()); builder.AddBigIntBlob(rsaParameters.Modulus); builder.AddBigIntBlob(rsaParameters.PublicExponent); builder.AddBigIntBlob(rsaParameters.Exponent); builder.AddBigIntBlob(rsaParameters.QInv); builder.AddBigIntBlob(rsaParameters.P); builder.AddBigIntBlob(rsaParameters.Q); builder.AddStringBlob(rsaKey.Comment); //save blob so far so we don't have to repeat later. byte[] commonBlob = builder.GetBlob(); builder.AddByte((byte)Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_CONFIRM); builder.InsertHeader(Agent.Message.SSH2_AGENTC_ADD_ID_CONSTRAINED); PrepareMessage(builder); agent.AnswerMessage(stream); RewindStream(); Agent.BlobHeader header = parser.ReadHeader(); Assert.That(header.BlobLength, Is.EqualTo(1)); Assert.That(header.Message, Is.EqualTo(Agent.Message.SSH_AGENT_FAILURE)); /* test adding key with confirm constraint */ agent = new TestAgent(); agent.ConfirmUserPermissionCallback = confirmCallback; PrepareMessage(builder); agent.AnswerMessage(stream); RewindStream(); header = parser.ReadHeader(); Assert.That(header.BlobLength, Is.EqualTo(1)); Assert.That(header.Message, Is.EqualTo(Agent.Message.SSH_AGENT_SUCCESS)); ISshKey returnedKey = agent.GetAllKeys().First(); Assert.That(returnedKey.Constraints.Count(), Is.EqualTo(1)); Assert.That(returnedKey.Constraints[0].Type, Is.EqualTo(Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_CONFIRM)); Assert.That(returnedKey.Constraints[0].Data, Is.Null); /* test adding key with lifetime constraint */ agent = new TestAgent(); builder.Clear(); builder.AddBytes(commonBlob); builder.AddByte((byte)Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_LIFETIME); builder.AddInt(10); builder.InsertHeader(Agent.Message.SSH2_AGENTC_ADD_ID_CONSTRAINED); PrepareMessage(builder); agent.AnswerMessage(stream); RewindStream(); header = parser.ReadHeader(); Assert.That(header.BlobLength, Is.EqualTo(1)); Assert.That(header.Message, Is.EqualTo(Agent.Message.SSH_AGENT_SUCCESS)); returnedKey = agent.GetAllKeys().First(); Assert.That(returnedKey.Constraints.Count(), Is.EqualTo(1)); Assert.That(returnedKey.Constraints[0].Type, Is.EqualTo(Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_LIFETIME)); Assert.That(returnedKey.Constraints[0].Data.GetType(), Is.EqualTo(Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_LIFETIME.GetDataType())); Assert.That(returnedKey.Constraints[0].Data, Is.EqualTo(10)); /* test adding key with multiple constraints */ agent = new TestAgent(); agent.ConfirmUserPermissionCallback = confirmCallback; builder.Clear(); builder.AddBytes(commonBlob); builder.AddByte((byte)Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_CONFIRM); builder.AddByte((byte)Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_LIFETIME); builder.AddInt(10); builder.InsertHeader(Agent.Message.SSH2_AGENTC_ADD_ID_CONSTRAINED); PrepareMessage(builder); agent.AnswerMessage(stream); RewindStream(); header = parser.ReadHeader(); Assert.That(header.BlobLength, Is.EqualTo(1)); Assert.That(header.Message, Is.EqualTo(Agent.Message.SSH_AGENT_SUCCESS)); returnedKey = agent.GetAllKeys().First(); Assert.That(returnedKey.Constraints.Count(), Is.EqualTo(2)); Assert.That(returnedKey.Constraints[0].Type, Is.EqualTo(Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_CONFIRM)); Assert.That(returnedKey.Constraints[0].Data, Is.Null); Assert.That(returnedKey.Constraints[1].Type, Is.EqualTo(Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_LIFETIME)); Assert.That(returnedKey.Constraints[1].Data, Is.EqualTo(10)); /* test adding key with multiple constraints in different order */ agent = new TestAgent(); agent.ConfirmUserPermissionCallback = confirmCallback; builder.Clear(); builder.AddBytes(commonBlob); builder.AddByte((byte)Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_LIFETIME); builder.AddInt(10); builder.AddByte((byte)Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_CONFIRM); builder.InsertHeader(Agent.Message.SSH2_AGENTC_ADD_ID_CONSTRAINED); PrepareMessage(builder); agent.AnswerMessage(stream); RewindStream(); header = parser.ReadHeader(); Assert.That(header.BlobLength, Is.EqualTo(1)); Assert.That(header.Message, Is.EqualTo(Agent.Message.SSH_AGENT_SUCCESS)); returnedKey = agent.GetAllKeys().First(); Assert.That(returnedKey.Constraints.Count(), Is.EqualTo(2)); Assert.That(returnedKey.Constraints[0].Type, Is.EqualTo(Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_LIFETIME)); Assert.That(returnedKey.Constraints[0].Data, Is.EqualTo(10)); Assert.That(returnedKey.Constraints[1].Type, Is.EqualTo(Agent.KeyConstraintType.SSH_AGENT_CONSTRAIN_CONFIRM)); Assert.That(returnedKey.Constraints[1].Data, Is.Null); }
public void TestAnswerSSH2_AGENTC_ADD_IDENTITY() { Agent agent = new TestAgent(); /* test adding RSA key */ BlobBuilder builder = new BlobBuilder(); RsaPrivateCrtKeyParameters rsaParameters = (RsaPrivateCrtKeyParameters)rsaKey.GetPrivateKeyParameters(); builder.AddStringBlob(rsaKey.Algorithm.GetIdentifierString()); builder.AddBigIntBlob(rsaParameters.Modulus); builder.AddBigIntBlob(rsaParameters.PublicExponent); builder.AddBigIntBlob(rsaParameters.Exponent); builder.AddBigIntBlob(rsaParameters.QInv); builder.AddBigIntBlob(rsaParameters.P); builder.AddBigIntBlob(rsaParameters.Q); builder.AddStringBlob(rsaKey.Comment); builder.InsertHeader(Agent.Message.SSH2_AGENTC_ADD_IDENTITY); PrepareMessage(builder); agent.AnswerMessage(stream); RewindStream(); Agent.BlobHeader header = parser.ReadHeader(); Assert.That(header.BlobLength, Is.EqualTo(1)); Assert.That(header.Message, Is.EqualTo(Agent.Message.SSH_AGENT_SUCCESS)); ISshKey returnedKey = agent.GetAllKeys().First(); Assert.That(returnedKey.GetPublicKeyParameters(), Is.InstanceOf<RsaKeyParameters>()); Assert.That(returnedKey.GetPrivateKeyParameters(), Is.InstanceOf<RsaKeyParameters>()); Assert.That(returnedKey.Size, Is.EqualTo(rsaKey.Size)); Assert.That(returnedKey.Comment, Is.EqualTo(rsaKey.Comment)); Assert.That(returnedKey.GetMD5Fingerprint(), Is.EqualTo(rsaKey.GetMD5Fingerprint())); /* test adding DSA key */ agent = new TestAgent(); builder.Clear(); DsaPublicKeyParameters dsaPublicParameters = (DsaPublicKeyParameters)dsaKey.GetPublicKeyParameters(); DsaPrivateKeyParameters dsaPrivateParameters = (DsaPrivateKeyParameters)dsaKey.GetPrivateKeyParameters(); builder.AddStringBlob(dsaKey.Algorithm.GetIdentifierString()); builder.AddBigIntBlob(dsaPublicParameters.Parameters.P); builder.AddBigIntBlob(dsaPublicParameters.Parameters.Q); builder.AddBigIntBlob(dsaPublicParameters.Parameters.G); builder.AddBigIntBlob(dsaPublicParameters.Y); builder.AddBigIntBlob(dsaPrivateParameters.X); builder.AddStringBlob(dsaKey.Comment); builder.InsertHeader(Agent.Message.SSH2_AGENTC_ADD_IDENTITY); PrepareMessage(builder); agent.AnswerMessage(stream); RewindStream(); header = parser.ReadHeader(); Assert.That(header.BlobLength, Is.EqualTo(1)); Assert.That(header.Message, Is.EqualTo(Agent.Message.SSH_AGENT_SUCCESS)); returnedKey = agent.GetAllKeys().First(); Assert.That(returnedKey.GetPublicKeyParameters(), Is.InstanceOf<DsaKeyParameters>()); Assert.That(returnedKey.GetPrivateKeyParameters(), Is.InstanceOf<DsaKeyParameters>()); Assert.That(returnedKey.Size, Is.EqualTo(dsaKey.Size)); Assert.That(returnedKey.Comment, Is.EqualTo(dsaKey.Comment)); Assert.That(returnedKey.GetMD5Fingerprint(), Is.EqualTo(dsaKey.GetMD5Fingerprint())); /* test adding ECDSA keys */ List<ISshKey> ecdsaKeysList = new List<ISshKey>(); ecdsaKeysList.Add(ecdsa256Key); ecdsaKeysList.Add(ecdsa384Key); ecdsaKeysList.Add(ecdsa521Key); foreach (ISshKey key in ecdsaKeysList) { agent = new TestAgent(); builder.Clear(); ECPublicKeyParameters ecdsaPublicParameters = (ECPublicKeyParameters)key.GetPublicKeyParameters(); ECPrivateKeyParameters ecdsaPrivateParameters = (ECPrivateKeyParameters)key.GetPrivateKeyParameters(); string ecdsaAlgorithm = key.Algorithm.GetIdentifierString(); builder.AddStringBlob(ecdsaAlgorithm); ecdsaAlgorithm = ecdsaAlgorithm.Replace(PublicKeyAlgorithmExt.ALGORITHM_ECDSA_SHA2_PREFIX, string.Empty); builder.AddStringBlob(ecdsaAlgorithm); builder.AddBlob(ecdsaPublicParameters.Q.GetEncoded()); builder.AddBigIntBlob(ecdsaPrivateParameters.D); builder.AddStringBlob(key.Comment); builder.InsertHeader(Agent.Message.SSH2_AGENTC_ADD_IDENTITY); PrepareMessage(builder); agent.AnswerMessage(stream); RewindStream(); header = parser.ReadHeader(); Assert.That(header.BlobLength, Is.EqualTo(1)); Assert.That(header.Message, Is.EqualTo(Agent.Message.SSH_AGENT_SUCCESS)); returnedKey = agent.GetAllKeys().First(); Assert.That(returnedKey.GetPublicKeyParameters(), Is.InstanceOf<ECPublicKeyParameters>()); Assert.That(returnedKey.GetPrivateKeyParameters(), Is.InstanceOf<ECPrivateKeyParameters>()); Assert.That(returnedKey.Size, Is.EqualTo(key.Size)); Assert.That(returnedKey.Comment, Is.EqualTo(key.Comment)); Assert.That(returnedKey.GetMD5Fingerprint(), Is.EqualTo(key.GetMD5Fingerprint())); Assert.That(returnedKey.Constraints.Count(), Is.EqualTo(0)); } /* test adding key that already is in KeyList does not create duplicate */ int startingCount = agent.GetAllKeys().Count(); Assert.That(startingCount, Is.Not.EqualTo(0)); PrepareMessage(builder); agent.AnswerMessage(stream); RewindStream(); header = parser.ReadHeader(); Assert.That(header.BlobLength, Is.EqualTo(1)); Assert.That(header.Message, Is.EqualTo(Agent.Message.SSH_AGENT_SUCCESS)); Assert.That(agent.GetAllKeys().Count(), Is.EqualTo(startingCount)); /* test locked => failure */ agent = new TestAgent(); agent.Lock(new byte[0]); PrepareMessage(builder); agent.AnswerMessage(stream); RewindStream(); header = parser.ReadHeader(); Assert.That(header.BlobLength, Is.EqualTo(1)); Assert.That(header.Message, Is.EqualTo(Agent.Message.SSH_AGENT_FAILURE)); Assert.That(agent.GetAllKeys().Count, Is.EqualTo(0)); }