public void VerifySignature(ApplicationArguments arguments)
        {
            ReadKeyFromFileCommand readPublicKeyFromFile = fileCommandProvider.GetReadPublicKeyFromFileCommand(arguments.PublicKeyPath);

            commandExecutor.Execute(readPublicKeyFromFile);

            byte[] contentToVerify;
            if (arguments.HasFileInput)
            {
                ReadFileCommand <byte[]> readFileToVerify = fileCommandProvider.GetReadFileCommand <byte[]>(arguments.FileInput);
                commandExecutor.Execute(readFileToVerify);
                contentToVerify = readFileToVerify.Result;
            }
            else
            {
                contentToVerify = encoding.GetBytes(arguments.Input);
            }

            byte[] signatureToVerify;
            if (base64.IsBase64(arguments.Signature))
            {
                signatureToVerify = base64.FromBase64String(arguments.Signature);
            }
            else
            {
                ReadFileCommand <byte[]> readSignatureToVerify = fileCommandProvider.GetReadFileCommand <byte[]>(arguments.Signature);
                commandExecutor.Execute(readSignatureToVerify);

                string base64Signature = encoding.GetString(readSignatureToVerify.Result);
                signatureToVerify = base64.FromBase64String(base64Signature);
            }

            VerifySignatureCommand verifySignature = signatureCommandProvider.GetVerifySignatureCommand(readPublicKeyFromFile.Result, contentToVerify, signatureToVerify);

            commandExecutor.Execute(verifySignature);
        }
Example #2
0
        //Based on https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key
        public string GetOpenSshEd25519PrivateKey(IAsymmetricKeyPair keyPair, string comment)
        {
            var privateKey = (IEcKey)keyPair.PrivateKey;

            if (keyPair.PrivateKey.IsEncrypted || !privateKey.IsCurve25519)
            {
                throw new InvalidOperationException("Only non-encrypted ed25519 keys are supported.");
            }

            byte[] openSshVersionHeader = encoding.GetBytes("openssh-key-v1\0");
            byte[] cipherName           = encoding.GetBytes("none");
            byte[] kdf        = encoding.GetBytes("none");
            byte[] kdfOptions = encoding.GetBytes("");

            byte[] numberOfKeys = BitConverter.GetBytes(1);
            if (BitConverter.IsLittleEndian)
            {
                numberOfKeys = numberOfKeys.Reverse().ToArray();
            }

            byte[] publicKeyWithHeader = base64.FromBase64String(GetEd25519PublicKeyContent((keyPair.PrivateKey)));
            byte[] publicKeyContent    = ecKeyProvider.GetEd25519PublicKeyFromCurve25519(privateKey);

            byte[] checkSumContent = randomGenerator.NextBytes(4);
            byte[] identifier      = encoding.GetBytes(sshCurveHeaders[privateKey.Curve]);

            var privateKeyParameters = (ECPrivateKeyParameters)PrivateKeyFactory.CreateKey(privateKey.Content);

            byte[] privateKeyContent = privateKeyParameters.D.ToByteArray();
            byte[] commentContent    = encoding.GetBytes(comment);

            using (var keyStream = new MemoryStream())
            {
                //Header ('encoded' buffer in https://github.com/openssh/openssh-portable/blob/master/sshkey.c :2957)
                using (var header = new MemoryStream())
                {
                    header.Write(openSshVersionHeader, 0, openSshVersionHeader.Length);
                    header.Write(LengthAsBytes(cipherName.Length), 0, 4);
                    header.Write(cipherName, 0, cipherName.Length);
                    header.Write(LengthAsBytes(kdf.Length), 0, 4);
                    header.Write(kdf, 0, kdf.Length);
                    header.Write(LengthAsBytes(kdfOptions.Length), 0, 4);
                    header.Write(kdfOptions, 0, kdfOptions.Length);
                    header.Write(numberOfKeys, 0, numberOfKeys.Length);
                    header.Write(LengthAsBytes(publicKeyWithHeader.Length), 0, 4);
                    header.Write(publicKeyWithHeader, 0, publicKeyWithHeader.Length);

                    header.WriteTo(keyStream);
                }

                //KeyContent ('encrypted' buffer in https://github.com/openssh/openssh-portable/blob/master/sshkey.c :2957)
                using (var content = new MemoryStream())
                {
                    content.Write(checkSumContent, 0, checkSumContent.Length);
                    content.Write(checkSumContent, 0, checkSumContent.Length);
                    content.Write(LengthAsBytes(identifier.Length), 0, 4);
                    content.Write(identifier, 0, identifier.Length);
                    content.Write(LengthAsBytes(publicKeyContent.Length), 0, 4);
                    content.Write(publicKeyContent, 0, publicKeyContent.Length);
                    content.Write(LengthAsBytes(privateKeyContent.Length + publicKeyContent.Length), 0, 4);
                    content.Write(privateKeyContent, 0, privateKeyContent.Length);
                    content.Write(publicKeyContent, 0, publicKeyContent.Length);
                    content.Write(LengthAsBytes(commentContent.Length), 0, 4);
                    content.Write(commentContent, 0, commentContent.Length);

                    //Block size for cipher "none" defined in https://github.com/openssh/openssh-portable/blob/master/cipher.c
                    byte iterator = 1;
                    while ((content.Length % 8) != 0)
                    {
                        content.WriteByte(iterator++);
                    }

                    byte[] contentLength = BitConverter.GetBytes((int)content.Length);
                    if (BitConverter.IsLittleEndian)
                    {
                        contentLength = contentLength.Reverse().ToArray();
                    }

                    keyStream.Write(contentLength, 0, 4);
                    content.WriteTo(keyStream);
                }

                return(base64.ToBase64String(keyStream.ToArray()));
            }
        }