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

Issue with latest version and missing constants #99

Closed
1337GameDev opened this issue Oct 17, 2019 · 43 comments
Closed

Issue with latest version and missing constants #99

1337GameDev opened this issue Oct 17, 2019 · 43 comments

Comments

@1337GameDev
Copy link

I currently cannot update versions of this library, and am stuck on v1.8.1.

If I update to 1.11.1, then the file "php72compat.php" fails to find the correct constants passed to "constant()"

This issue will then generate a warning for EVERY constant needed, even if my PHP version is v7.1 or v7.2.

Can this be investigated?

I can reproduce it by using Certainty, and updating to the latest, and then trying to execute RemoteFetch->getLatestBundle().

@paragonie-scott
Copy link
Member

Can this be investigated?

Yes! :)

Let's start with: What operating system are you using? There might be something weird with your OS-provided packages that's creating this behavior.

@1337GameDev
Copy link
Author

I am using Win10 Enterprise 1809 and PHP 7.2.15 x64 NTS.

I am running this in IIS, for a WordPress installation, for development purposes. The correct Version of PHP is specified in my PATH and in IIS (site and server).

@paragonie-scott
Copy link
Member

Quick fix: Open php.ini and remove the ; in front of extension=sodium and restart IIS.

I'll look into reproducing this issue and report back as soon as I'm aware of what's happening.

@paragonie-scott
Copy link
Member

Okay, this might solve the problem: 76d239d

If the class doesn't exist, lib/php72compat.php fails as you report. This might be a weird autoloader issue with PHP on Windows. Easiest fix: Make sure the autoloader has run first.

@paragonie-scott
Copy link
Member

If you'd like to help confirm the fix: Replace vendor/paragonie/sodium_compat/lib/php72compat.php with this file, and tell me if this behavior goes away.

If so, I'll release v1.11.2 with the fix tonight.

@paragonie-scott
Copy link
Member

Actually, that might have been premature. Sorry.

You'll want this file instead.

The previous one works locally but not when installed as a dependency.

@1337GameDev
Copy link
Author

Okay, this might solve the problem: 76d239d

If the class doesn't exist, lib/php72compat.php fails as you report. This might be a weird autoloader issue with PHP on Windows. Easiest fix: Make sure the autoloader has run first.

Not sure how to force the autoloader to run first, I use composer and standard using statements (does the order of using statements change the order of class-loading?) Not sure how composer works under the hood really.

I can test that file in a little bit.

@paragonie-scott
Copy link
Member

(does the order of using statements change the order of class-loading?)

It does! But also, it shouldn't matter at all. The autoloader should be registered before lib/php72compat.php ever has a chance to execute.

Not sure how to force the autoloader to run first

There's nothing you have to do. That's my responsibility. :)

@1337GameDev
Copy link
Author

Actually, that might have been premature. Sorry.

You'll want this file instead.

The previous one works locally but not when installed as a dependency.

Tested that version, and it still throws the mentioned warnings.

Hmm. I am quite stumped. This development will eventually be deployed to a shared hosting environment, so I wouldn't be able to rely on a php ini change.

Is there any other info I could provide?

@paragonie-scott
Copy link
Member

Tested that version, and it still throws the mentioned warnings.

This tells me: The autoloader isn't working. I wonder if I have to hijack Composer's?

@paragonie-scott
Copy link
Member

paragonie-scott commented Oct 17, 2019

In autoload.php, can you add these lines right above the line where lib/php72compat.php is loaded?

    if (DIRECTORY_SEPARATOR === '\\') {
        assert(ParagonIE_Sodium_Compat::polyfill_is_fast());
    }

The line that follows should be:

    require_once dirname(__FILE__) . '/lib/php72compat.php'

paragonie-security added a commit that referenced this issue Oct 17, 2019
Assert that the class exists before attempting to load
lib/php72compat.php.
@paragonie-scott
Copy link
Member

I've thus far been unsuccessful in reproducing the issues in my own environments.

One trick you might want to try is to check ParagonIE_Sodium_Compat::polyfill_is_fast() before invoking RemoteFetch at all.

@1337GameDev
Copy link
Author

if (DIRECTORY_SEPARATOR === '\\') {
        assert(ParagonIE_Sodium_Compat::polyfill_is_fast());
    }

Which autoload?

The one under sodium_compat or, the one under vendor?

@1337GameDev
Copy link
Author

I've thus far been unsuccessful in reproducing the issues in my own environments.

One trick you might want to try is to check ParagonIE_Sodium_Compat::polyfill_is_fast() before invoking RemoteFetch at all.

I have seen that method before in the documentation. Doesn't this method just check if sodium will be efficiently ran?

@paragonie-scott
Copy link
Member

In order for this to return anything, it has to guarantee that ParagonIE_Sodium_Compat has already been loaded before the line that includes lib/php72compat.php is executed.

@paragonie-scott
Copy link
Member

Which autoload?

The one under sodium_compat or, the one under vendor?

Under vendor. Specifically, vendor/paragonie/sodium_compat/autoload.php.

@1337GameDev
Copy link
Author

In order for this to return anything, it has to guarantee that ParagonIE_Sodium_Compat has already been loaded before the line that includes lib/php72compat.php is executed.

Hmm, how is that line actually ran from a separate PHP file? Do I have to load the right file, in a "using" statement to get access to that?

Hmm, how is that file generally invoked? Is that autoload file picked up by composer, and then invoked when a "using" statement is present in a php file?

@paragonie-scott
Copy link
Member

paragonie-scott commented Oct 17, 2019

The answer is in the composer configuration:

"files": ["autoload.php"]

The hotfix I provided above should guarantee that ParagonIE_Sodium_Compat exists before the lib/php72compat.php file is invoked.

If you are still getting errors, then the problem is unrelated to race conditions with the autoloader. In that case, it might be some weird Windows bug that needs to be reported to the PHP team.

@1337GameDev
Copy link
Author

The answer is in the composer configuration:

"files": ["autoload.php"]

The hotfix I provided above should guarantee that ParagonIE_Sodium_Compat exists before the lib/php72compat.php file is invoked.

If you are still getting errors, then the problem is unrelated to race conditions with the autoloader. In that case, it might be some weird Windows bug that needs to be reported to the PHP team.

Ahhhh, so each "dependency" does/can have a composer.json that dictates how the dependency is to be loaded?

Sorry if this is basic, haven't delved too much into how composer works, just that I know how to use it

@dana321
Copy link

dana321 commented Oct 17, 2019

I have the same problem.

The issue is that it can't read the constants within the class.

Removing the loop and placing the following in my code fixes the problem in php72compat.php:

const SODIUM_BASE64_VARIANT_ORIGINAL = 1;
const SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING = 3;
const SODIUM_BASE64_VARIANT_URLSAFE = 5;
const SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING = 7;
const SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES = 32;
const SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES = 0;
const SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES = 12;
const SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES = 16;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES = 32;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES = 0;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES = 8;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES = 16;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES = 32;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES = 0;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES = 12;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES = 16;
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES = 32;
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NSECBYTES = 0;
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES = 24;
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES = 16;
const SODIUM_CRYPTO_AUTH_BYTES = 32;
const SODIUM_CRYPTO_AUTH_KEYBYTES = 32;
const SODIUM_CRYPTO_BOX_SEALBYTES = 16;
const SODIUM_CRYPTO_BOX_SECRETKEYBYTES = 32;
const SODIUM_CRYPTO_BOX_PUBLICKEYBYTES = 32;
const SODIUM_CRYPTO_BOX_KEYPAIRBYTES = 64;
const SODIUM_CRYPTO_BOX_MACBYTES = 16;
const SODIUM_CRYPTO_BOX_NONCEBYTES = 24;
const SODIUM_CRYPTO_BOX_SEEDBYTES = 32;
const SODIUM_CRYPTO_KDF_BYTES_MIN = 16;
const SODIUM_CRYPTO_KDF_BYTES_MAX = 64;
const SODIUM_CRYPTO_KDF_CONTEXTBYTES = 8;
const SODIUM_CRYPTO_KDF_KEYBYTES = 32;
const SODIUM_CRYPTO_KX_BYTES = 32;
const SODIUM_CRYPTO_KX_PRIMITIVE = 'x25519blake2b';
const SODIUM_CRYPTO_KX_SEEDBYTES = 32;
const SODIUM_CRYPTO_KX_KEYPAIRBYTES = 64;
const SODIUM_CRYPTO_KX_PUBLICKEYBYTES = 32;
const SODIUM_CRYPTO_KX_SECRETKEYBYTES = 32;
const SODIUM_CRYPTO_KX_SESSIONKEYBYTES = 32;
const SODIUM_CRYPTO_GENERICHASH_BYTES = 32;
const SODIUM_CRYPTO_GENERICHASH_BYTES_MIN = 16;
const SODIUM_CRYPTO_GENERICHASH_BYTES_MAX = 64;
const SODIUM_CRYPTO_GENERICHASH_KEYBYTES = 32;
const SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN = 16;
const SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX = 64;
const SODIUM_CRYPTO_PWHASH_SALTBYTES = 16;
const SODIUM_CRYPTO_PWHASH_STRPREFIX = '$argon2id$';
const SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13 = 1;
const SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13 = 2;
const SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE = 33554432;
const SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE = 4;
const SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE = 134217728;
const SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE = 6;
const SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE = 536870912;
const SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE = 8;
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES = 32;
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX = '$7$';
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE = 534288;
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE = 16777216;
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE = 33554432;
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE = 1073741824;
const SODIUM_CRYPTO_SCALARMULT_BYTES = 32;
const SODIUM_CRYPTO_SCALARMULT_SCALARBYTES = 32;
const SODIUM_CRYPTO_SHORTHASH_BYTES = 8;
const SODIUM_CRYPTO_SHORTHASH_KEYBYTES = 16;
const SODIUM_CRYPTO_SECRETBOX_KEYBYTES = 32;
const SODIUM_CRYPTO_SECRETBOX_MACBYTES = 16;
const SODIUM_CRYPTO_SECRETBOX_NONCEBYTES = 24;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES = 17;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES = 24;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES = 32;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH = 0;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL = 1;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY = 2;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL = 3;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX = 0x3fffffff80;
const SODIUM_CRYPTO_SIGN_BYTES = 64;
const SODIUM_CRYPTO_SIGN_SEEDBYTES = 32;
const SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES = 32;
const SODIUM_CRYPTO_SIGN_SECRETKEYBYTES = 64;
const SODIUM_CRYPTO_SIGN_KEYPAIRBYTES = 96;
const SODIUM_CRYPTO_STREAM_KEYBYTES = 32;
const SODIUM_CRYPTO_STREAM_NONCEBYTES = 24;

const does not throw an error if it is already defined.

@paragonie-scott
Copy link
Member

Yes, but can const be used in PHP 5.2?

@dana321
Copy link

dana321 commented Oct 17, 2019

its only included if its php 7.x anyway?

@dana321
Copy link

dana321 commented Oct 17, 2019

This is the first time i've tried this library, and it didn't work. Just sharing my fix, i really want to get on with trying out ECC in php.

@paragonie-scott
Copy link
Member

48b9237

This should work, then.

@paragonie-scott
Copy link
Member

Okay, update to ^1.11.2 in Composer. This should be fixed.

@dana321
Copy link

dana321 commented Oct 17, 2019

Ok, i have updated and can confirm it works on PHP 7.1 on Windows 10 / WAMP 7.1

Thank you.

@1337GameDev
Copy link
Author

Hmm, I still encounter an issue. I've made sure to regenerate my autoloader, and have updated to the latest for sodium_compat and certainty. All the constants seem to be defined already. What can I provide to help?

Notice: Constant SODIUM_LIBRARY_VERSION_MAJOR already defined in \vendor\paragonie\sodium_compat\lib\php72compat_const.php on line 3

@1337GameDev
Copy link
Author

For the using statement, I use Certainty with this using:

use ParagonIE\Certainty\RemoteFetch;

Is there a different one that should be used?

@paragonie-scott
Copy link
Member

That's a different error! We're moving in the right direction.

Try version 1.11.3?

@paragonie-scott
Copy link
Member

(Apologies for anyone not participating in this thread. I can only use releases to guarantee complex fixes are deployed in these users' computers since I cannot reproduce the issue on my own computers.)

@1337GameDev
Copy link
Author

Closer ;) Complains differently about all the constants ;)

Warning: constant(): Couldn't find constant ParagonIE_Sodium_Compat::BASE64_VARIANT_ORIGINAL in D:\inetpub\wwwroot...\vendor\paragonie\sodium_compat\lib\php72compat.php on line 93

@paragonie-scott
Copy link
Member

What happens if you run php.exe vendor\paragonie\sodium_compat\lib\php72compat.php directly?

@1337GameDev
Copy link
Author

No output from command line (assuming success because no warnings given)

@paragonie-scott
Copy link
Member

Okay, I think I know the issue. Run these two commands in a few minutes and it should force-update to 1.11.3 (the actual release).

composer clean
composer update

If it doesn't update, you might need to delete vendor\paragonie\sodium_compat first.

@dana321
Copy link

dana321 commented Oct 17, 2019

Just to let you know, updated and it still works for me.

@1337GameDev
Copy link
Author

Seems to have fixed it. Odd, because I deleted the vendor folder before. Must have been some leftover files in my project that I didn't delete.

Now on to the certainty issues the seem to linger.

@1337GameDev
Copy link
Author

I'll close this for now, as it seems to be fixed, nd my issue is another area now.

Thanks for all your help, it is much appreciated!

@paragonie-scott
Copy link
Member

Happy to hear that!

@paragonie-scott
Copy link
Member

I think this may be the result of https://bugs.php.net/bug.php?id=77621 since it was fixed in PHP 7.2.16 (see COM).

@1337GameDev
Copy link
Author

Nice find! It DOES seem connected. Sadly, our environment has to match production, and they use PHP 7.2.15. They'll update eventually ;)

Thanks for the update on this; it is very much appreciated!

@paragonie-scott
Copy link
Member

Actually, that might not be related. I opened https://bugs.php.net/bug.php?id=78692 just in case it is a new PHP bug.

@cmb69
Copy link

cmb69 commented Oct 18, 2019

The COM bug is definitely unrelated, but I wonder whether OPcache was enabled when the problems occured, and whether disabling OPcache would have solved the issue.

@dana321
Copy link

dana321 commented Oct 18, 2019

PHP 7.x is pretty buggy especially the .1 and .2 branches in experience, the whole reason why .3 was created.

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

No branches or pull requests

4 participants