Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add preliminary EdDSA validation support #239

Closed
wants to merge 1 commit into from

Conversation

ntadej
Copy link

@ntadej ntadej commented Jan 16, 2022

Add preliminary EdDSA validation support (partially closes #187 as signing is still missing). I tested with valid and invalid signature and it seems to work. Note that more testing is probably needed.

Some comments:

  • Uses https://github.com/orlp/ed25519.git like the primary Sparkle project, causes minimal size increase of the final dll.
  • Public key verfication is not there yet, I guess it is enough to just do the Base64 decoding + size check?
  • Not sure I updated bakefile/vcxproj correctly. I get some errors, but it everything looks fine. The only thing is that the format changed a bit (I guess I'm using a different version of bakefile as the current files were generated with).
  • Do we need that complicated file reading? I admit I took the first snippet from StackOverflow on how to read full files on windows.
  • RC integration not tested (I'm not primarily a Windows developer, I'm just trying to port one of my apps to Windows).

Tagging @kornelski and @vslavik.

Comment on lines +290 to +295
std::vector<unsigned char> Base64ToUnsignedBin(const std::string& base64)
{
std::string bin = Base64ToBin(base64);
return std::vector<unsigned char>(bin.data(), bin.data() + bin.length() + 1);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see my comment below

Suggested change
std::vector<unsigned char> Base64ToUnsignedBin(const std::string& base64)
{
std::string bin = Base64ToBin(base64);
return std::vector<unsigned char>(bin.data(), bin.data() + bin.length() + 1);
}

Comment on lines +352 to +358
std::vector<unsigned char> signature = Base64ToUnsignedBin(signature_base64);
std::vector<unsigned char> key = Base64ToUnsignedBin(Settings::GetEdDSAPubKey());

int result = ed25519_verify(signature.data(),
buffer,
bytes_read,
key.data());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need in additional intermediate copy of the data here:

Suggested change
std::vector<unsigned char> signature = Base64ToUnsignedBin(signature_base64);
std::vector<unsigned char> key = Base64ToUnsignedBin(Settings::GetEdDSAPubKey());
int result = ed25519_verify(signature.data(),
buffer,
bytes_read,
key.data());
const std::string signature = Base64ToBin(signature_base64);
const std::string key = Base64ToBin(Settings::GetEdDSAPubKey());
int result = ed25519_verify(reinterpret_cast<const unsigned char*>(signature.data()),
buffer,
bytes_read,
reinterpret_cast<const unsigned char*>(key.data()));


DWORD size = GetFileSize(payload, NULL);
DWORD bytes_read = 0;
unsigned char *buffer = new unsigned char[size + 1];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace with std::vector<unsigned char>

Comment on lines +338 to +339
HANDLE payload;
payload = CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
Copy link
Contributor

@Youw Youw Jan 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
HANDLE payload;
payload = CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
CFile payload (_wfopen(filename.c_str(), L"rb"));

always prefer using standard C/C++ (in this particular case _wfopen is not exactly standard C, but that is lesser evil in this case) instead of Platform-specific functionality, if possible
(sample: https://stackoverflow.com/a/14002993/3697939)

Comment on lines +307 to +308
// TODO: validate
(void)key;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how ed25519_verify reads they key: https://github.com/orlp/ed25519/blob/7fa6712ef5d581a6981ec2b08ee623314cd1d1c4/src/verify.c#L58
We can do exactly the same to verify the key.
Make sure to verify that the key len (after decode from base64) is exactly 32 bytes byfore passing into ge_frombytes_negate_vartime

}
buffer[bytes_read] = '\0';

std::vector<unsigned char> signature = Base64ToUnsignedBin(signature_base64);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verify that the signature is exactly 64 bytes before passing it into ed25519_verify

buffer[bytes_read] = '\0';

std::vector<unsigned char> signature = Base64ToUnsignedBin(signature_base64);
std::vector<unsigned char> key = Base64ToUnsignedBin(Settings::GetEdDSAPubKey());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verify that the key is exactly 32 bytes before passing it into ed25519_verify

@purejava
Copy link

purejava commented Jan 7, 2023

@ntadej, @Youw, do you see any chance to proceed with this PR?
Thanks.

@purejava
Copy link

purejava commented Jan 8, 2023

The reason why I am asking is, that I have created Java bindings for WinSparkle and we want to use these to update Cryptomator on Windows, that securely stores vaults in cloud services.

@ntadej
Copy link
Author

ntadej commented Jan 8, 2023

I am planning to, but Windows is currently at the bottom of priority list for my project.

@geraldcombs
Copy link

I think I've fixed the issues identified by @Youw in https://github.com/geraldcombs/winsparkle/tree/eddsa-updates. The only outstanding issue is that SignatureVerifier::VerifyEdDSAPubKey is still a placeholder. I think the proper fix would be to add a corresponding function to the ed25519 public API.

@ntadej if my changes look OK to you, feel free to grab them and add them to this PR (and assign yourself authorship if you'd like). Otherwise I'd be happy to open a separate PR.

@vslavik
Copy link
Owner

vslavik commented May 6, 2023

@geraldcombs Thanks!

The only outstanding issue is that SignatureVerifier::VerifyEdDSAPubKey is still a placeholder. I think the proper fix would be to add a corresponding function to the ed25519 public API.

Let's make this simpler: VerifyEdDSAPubKey has little usefulness and the verification is done at signature checking time anyway, so we can either just remove this part or do what was initially suggested:

Public key verfication is not there yet, I guess it is enough to just do the Base64 decoding + size check?

@vslavik
Copy link
Owner

vslavik commented May 6, 2023

Otherwise I'd be happy to open a separate PR.

Oh, sorry, forgot to say: please do.

@ntadej
Copy link
Author

ntadej commented May 6, 2023

Yes, sorry for lack of activity here. I also propose you open a separate PR so it will be easier to iterate for you.

@geraldcombs
Copy link

Oh, sorry, forgot to say: please do.

Done in #254.

@vslavik
Copy link
Owner

vslavik commented May 21, 2023

#254

@vslavik vslavik closed this May 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support EdDSA signatures
5 participants