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

Expired token for secure map is not properly renewed #16

Closed
SergeyBarskiy opened this issue Mar 1, 2018 · 5 comments
Closed

Expired token for secure map is not properly renewed #16

SergeyBarskiy opened this issue Mar 1, 2018 · 5 comments

Comments

@SergeyBarskiy
Copy link

When a token expires and it needs to be renewed, a cryptographic exception is thrown with text of Bad Length. The code below reproduces the issue. The actual issue is that GenerateToken gets double encrypted on renewal because the TokenRequest property is replaced inside Token Provider

TokenRequest = CryptoProvider.Encrypt(TokenRequest, _publicKey.Exponent, _publicKey.Modulus);

Thank you!

GenerateToken t = new GenerateToken("user", "password");
var publicKey = new PublicKeyResponse
{
PublicKey = "10001",
Mod = "a92d33f398ef1d71c616730807b5722312ed42b94f0891299281abcc4fb7350b5eab970a6e52953fc695295735b9fd347b8b3fa7aa2f12c4a3ed423875aa276d"
};
GenerateToken e = new RsaEncrypter().Encrypt(t, publicKey.Exponent, publicKey.Modulus);

        GenerateToken b = new RsaEncrypter().Encrypt(e, publicKey.Exponent, publicKey.Modulus); 
@davetimmins
Copy link
Owner

I think I see the issue, though at the moment I don't have an ArcGIS Server readily available to test out a fix. In the CryptoProvider, adding a check to see if the TokenRequest is already encrypted should do it. If you like you could try it out by implementing your own CryptoProviderFactory.Get function like so. First create the fixed version

public class RsaEncrypterCustom : ICryptoProvider
{
    public Operation.GenerateToken Encrypt(Operation.GenerateToken tokenRequest, byte[] exponent, byte[] modulus)
    {
        LiteGuard.Guard.AgainstNullArgument(nameof(tokenRequest), tokenRequest);
        LiteGuard.Guard.AgainstNullArgument(nameof(exponent), exponent);
        LiteGuard.Guard.AgainstNullArgument(nameof(modulus), modulus);

        // this is the fix (hopefully)
        if (tokenRequest.Encrypted == true)
        {
            return tokenRequest;
        }

        using (var rsa = new System.Security.Cryptography.RSACryptoServiceProvider(512))
        {
            var rsaParms = new System.Security.Cryptography.RSAParameters
            {
                Exponent = exponent,
                Modulus = modulus
            };
            rsa.ImportParameters(rsaParms);

            var encryptedUsername = rsa.Encrypt(Encoding.UTF8.GetBytes(tokenRequest.Username), false).BytesToHex();
            var encryptedPassword = rsa.Encrypt(Encoding.UTF8.GetBytes(tokenRequest.Password), false).BytesToHex();
            var encryptedClient = string.IsNullOrWhiteSpace(tokenRequest.Client) ? "" : rsa.Encrypt(Encoding.UTF8.GetBytes(tokenRequest.Client), false).BytesToHex();
            var encryptedExpiration = rsa.Encrypt(Encoding.UTF8.GetBytes(tokenRequest.ExpirationInMinutes.ToString()), false).BytesToHex();
            var encryptedReferer = string.IsNullOrWhiteSpace(tokenRequest.Referer) ? "" : rsa.Encrypt(Encoding.UTF8.GetBytes(tokenRequest.Referer), false).BytesToHex();
            
            tokenRequest.Encrypt(encryptedUsername, encryptedPassword, encryptedExpiration, encryptedClient, encryptedReferer);

            return tokenRequest;
        }
    }
}

then somewhere at the start of your app where you enable the encryption

CryptoProviderFactory.Enabled = true;
CryptoProviderFactory.Get = () => new RsaEncrypterCustom();

@SergeyBarskiy
Copy link
Author

Yep, that should do it. Thank you as always!

@davetimmins
Copy link
Owner

If that fixes it can you let me know and I'll do a new release with the fix.

@SergeyBarskiy
Copy link
Author

Thank you, Dave. We have a developer assigned to this task. We should have an answer today or Monday.

@SergeyBarskiy
Copy link
Author

Thanks for your help, Dave. The suggested fix worked.
// this is the fix (hopefully)
if (tokenRequest.Encrypted == true)
{
return tokenRequest;
}

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

2 participants