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

Implement parsec authentication #1543

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ci/config/config.compression.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"SocketPath": "./../../../../.ci/run/mysql/mysqld.sock",
"PasswordlessUser": "no_password",
"SecondaryDatabase": "testdb2",
"UnsupportedFeatures": "Ed25519,QueryAttributes,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,UnixDomainSocket,ZeroDateTime",
"UnsupportedFeatures": "Ed25519,QueryAttributes,ParsecAuthentication,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,UnixDomainSocket,ZeroDateTime",
"MySqlBulkLoaderLocalCsvFile": "../../../../tests/TestData/LoadData_UTF8_BOM_Unix.CSV",
"MySqlBulkLoaderLocalTsvFile": "../../../../tests/TestData/LoadData_UTF8_BOM_Unix.TSV"
}
Expand Down
2 changes: 1 addition & 1 deletion .ci/config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"SocketPath": "./../../../../.ci/run/mysql/mysqld.sock",
"PasswordlessUser": "no_password",
"SecondaryDatabase": "testdb2",
"UnsupportedFeatures": "Ed25519,QueryAttributes,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,UnixDomainSocket,ZeroDateTime",
"UnsupportedFeatures": "Ed25519,QueryAttributes,ParsecAuthentication,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,UnixDomainSocket,ZeroDateTime",
"MySqlBulkLoaderLocalCsvFile": "../../../../tests/TestData/LoadData_UTF8_BOM_Unix.CSV",
"MySqlBulkLoaderLocalTsvFile": "../../../../tests/TestData/LoadData_UTF8_BOM_Unix.TSV"
}
Expand Down
10 changes: 8 additions & 2 deletions .ci/docker-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ MYSQL_EXTRA=
MYSQL=mysql

if [[ "$IMAGE" == mariadb* ]]; then
MYSQL_EXTRA='--in-predicate-conversion-threshold=100000'
MYSQL_EXTRA='--in-predicate-conversion-threshold=100000 --plugin-maturity=beta'
fi
if [ "$IMAGE" == "mariadb:11.4" ]; then
if [ "$IMAGE" == "mariadb:11.4" ] || [ "$IMAGE" == "mariadb:11.6" ]; then
MYSQL='mariadb'
fi

Expand Down Expand Up @@ -79,6 +79,12 @@ for i in `seq 1 120`; do
if [ $? -ne 0 ]; then exit $?; fi
fi

if [[ $OMIT_FEATURES != *"ParsecAuthentication"* ]]; then
echo "Installing auth_parsec component"
docker exec mysql bash -c "$MYSQL -uroot -ptest < /etc/mysql/conf.d/init_parsec.sql"
if [ $? -ne 0 ]; then exit $?; fi
fi

if [[ $OMIT_FEATURES != *"QueryAttributes"* ]]; then
echo "Installing query_attributes component"
docker exec mysql $MYSQL -uroot -ptest -e "INSTALL COMPONENT 'file://component_query_attributes';"
Expand Down
3 changes: 3 additions & 0 deletions .ci/server/init_parsec.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
INSTALL SONAME 'auth_parsec';
CREATE USER 'parsec-user'@'%' IDENTIFIED via parsec using PASSWORD('P@rs3c-Pa55');
GRANT ALL PRIVILEGES ON *.* TO 'parsec-user'@'%';
22 changes: 13 additions & 9 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
arguments: 'tests\IntegrationTests\IntegrationTests.csproj -c MySqlData'
testRunTitle: 'MySql.Data integration tests'
env:
DATA__UNSUPPORTEDFEATURES: 'Ed25519,QueryAttributes,StreamingResults,TlsFingerprintValidation,UnixDomainSocket'
DATA__UNSUPPORTEDFEATURES: 'Ed25519,QueryAttributes,ParsecAuthentication,StreamingResults,TlsFingerprintValidation,UnixDomainSocket'
DATA__CONNECTIONSTRING: 'server=localhost;port=3306;user id=root;password=test;database=mysqltest;ssl mode=none;DefaultCommandTimeout=3600'
DATA__CERTIFICATESPATH: '$(Build.Repository.LocalPath)\.ci\server\certs\'
DATA__MYSQLBULKLOADERLOCALCSVFILE: '$(Build.Repository.LocalPath)\tests\TestData\LoadData_UTF8_BOM_Unix.CSV'
Expand Down Expand Up @@ -120,7 +120,7 @@ jobs:
arguments: '-c Release --no-restore -p:TestTfmsInParallel=false'
testRunTitle: ${{ format('{0}, $(Agent.OS), {1}, {2}', 'mysql:8.0', 'net481/net9.0', 'No SSL') }}
env:
DATA__UNSUPPORTEDFEATURES: 'Ed25519,QueryAttributes,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,UnixDomainSocket'
DATA__UNSUPPORTEDFEATURES: 'Ed25519,QueryAttributes,ParsecAuthentication,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,UnixDomainSocket'
DATA__CONNECTIONSTRING: 'server=localhost;port=3306;user id=mysqltest;password=test;database=mysqltest;ssl mode=none;DefaultCommandTimeout=3600;AllowPublicKeyRetrieval=True;UseCompression=True'

- job: windows_integration_tests_2
Expand Down Expand Up @@ -158,7 +158,7 @@ jobs:
arguments: '-c Release --no-restore -p:TestTfmsInParallel=false'
testRunTitle: ${{ format('{0}, $(Agent.OS), {1}, {2}', 'mysql:8.0', 'net8.0', 'No SSL') }}
env:
DATA__UNSUPPORTEDFEATURES: 'Ed25519,QueryAttributes,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,UnixDomainSocket'
DATA__UNSUPPORTEDFEATURES: 'Ed25519,QueryAttributes,ParsecAuthentication,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,UnixDomainSocket'
DATA__CONNECTIONSTRING: 'server=localhost;port=3306;user id=mysqltest;password=test;database=mysqltest;ssl mode=none;DefaultCommandTimeout=3600;AllowPublicKeyRetrieval=True'

- job: linux_integration_tests
Expand All @@ -171,27 +171,31 @@ jobs:
'MySQL 8.0':
image: 'mysql:8.0'
connectionStringExtra: 'AllowPublicKeyRetrieval=True'
unsupportedFeatures: 'Ed25519,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,ZeroDateTime'
unsupportedFeatures: 'Ed25519,ParsecAuthentication,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,ZeroDateTime'
'MySQL 8.4':
image: 'mysql:8.4'
connectionStringExtra: 'AllowPublicKeyRetrieval=True'
unsupportedFeatures: 'Ed25519,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,ZeroDateTime'
unsupportedFeatures: 'Ed25519,ParsecAuthentication,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,ZeroDateTime'
'MySQL 9.2':
image: 'mysql:9.2'
connectionStringExtra: 'AllowPublicKeyRetrieval=True'
unsupportedFeatures: 'Ed25519,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,ZeroDateTime'
unsupportedFeatures: 'Ed25519,ParsecAuthentication,Redirection,StreamingResults,Tls11,TlsFingerprintValidation,ZeroDateTime'
'MariaDB 10.6':
image: 'mariadb:10.6'
connectionStringExtra: ''
unsupportedFeatures: 'CachingSha2Password,CancelSleepSuccessfully,Json,RoundDateTime,QueryAttributes,Redirection,Sha256Password,Tls11,TlsFingerprintValidation,UuidToBin'
unsupportedFeatures: 'CachingSha2Password,CancelSleepSuccessfully,Json,RoundDateTime,QueryAttributes,ParsecAuthentication,Redirection,Sha256Password,Tls11,TlsFingerprintValidation,UuidToBin'
'MariaDB 10.11':
image: 'mariadb:10.11'
connectionStringExtra: ''
unsupportedFeatures: 'CachingSha2Password,CancelSleepSuccessfully,Json,RoundDateTime,QueryAttributes,Redirection,Sha256Password,Tls11,TlsFingerprintValidation,UuidToBin'
unsupportedFeatures: 'CachingSha2Password,CancelSleepSuccessfully,Json,RoundDateTime,QueryAttributes,ParsecAuthentication,Redirection,Sha256Password,Tls11,TlsFingerprintValidation,UuidToBin'
'MariaDB 11.4':
image: 'mariadb:11.4'
connectionStringExtra: ''
unsupportedFeatures: 'CachingSha2Password,CancelSleepSuccessfully,Json,RoundDateTime,QueryAttributes,Sha256Password,Tls11,UuidToBin,Redirection'
unsupportedFeatures: 'CachingSha2Password,CancelSleepSuccessfully,Json,RoundDateTime,QueryAttributes,ParsecAuthentication,Sha256Password,Tls11,UuidToBin,Redirection'
'MariaDB 11.6':
image: 'mariadb:11.6'
connectionStringExtra: ''
unsupportedFeatures: 'CachingSha2Password,CancelSleepSuccessfully,Json,RoundDateTime,QueryAttributes,Redirection,Sha256Password,Tls11,UuidToBin'
steps:
- template: '.ci/integration-tests-steps.yml'
parameters:
Expand Down
2 changes: 1 addition & 1 deletion docs/content/home.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Server | Versions | Notes
Amazon Aurora RDS | 2.x, 3.x | Use `Pipelining=False` [for Aurora 2.x](https://mysqlconnector.net/troubleshooting/aurora-freeze/)
Azure Database for MySQL | 5.7, 8.0 | Single Server and Flexible Server
Google Cloud SQL for MySQL | 5.6, 5.7, 8.0 |
MariaDB | 10.x (**10.6**, **10.11**), 11.x (**11.4**) |
MariaDB | 10.x (**10.6**, **10.11**), 11.x (**11.4**, **11.6**) |
MySQL | 5.5, 5.6, 5.7, 8.x (**8.0**, **8.4**), 9.x (**9.2**) | 5.5 is EOL and has some [compatibility issues](https://github.com/mysql-net/MySqlConnector/issues/1192); 5.6 and 5.7 are EOL
Percona Server | 5.6, 5.7, 8.0 |
PlanetScale | | See PlanetScale [MySQL compatibility notes](https://planetscale.com/docs/reference/mysql-compatibility)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Runtime.CompilerServices;

namespace Chaos.NaCl
{
internal static class CryptoBytes
{
public static void Wipe(byte[] data)
{
if (data == null)
throw new ArgumentNullException("data");
InternalWipe(data, 0, data.Length);
}

// Secure wiping is hard
// * the GC can move around and copy memory
// Perhaps this can be avoided by using unmanaged memory or by fixing the position of the array in memory
// * Swap files and error dumps can contain secret information
// It seems possible to lock memory in RAM, no idea about error dumps
// * Compiler could optimize out the wiping if it knows that data won't be read back
// I hope this is enough, suppressing inlining
// but perhaps `RtlSecureZeroMemory` is needed
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void InternalWipe(byte[] data, int offset, int count)
{
Array.Clear(data, offset, count);
}

// shallow wipe of structs
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void InternalWipe<T>(ref T data)
where T : struct
{
data = default(T);
}
}
}
50 changes: 50 additions & 0 deletions src/MySqlConnector.Authentication.Ed25519/Chaos.NaCl/Ed25519.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Security.Cryptography;
using Chaos.NaCl.Internal.Ed25519Ref10;

namespace Chaos.NaCl
{
internal static class Ed25519
{
public static readonly int PublicKeySizeInBytes = 32;
public static readonly int SignatureSizeInBytes = 64;
public static readonly int ExpandedPrivateKeySizeInBytes = 32 * 2;
public static readonly int PrivateKeySeedSizeInBytes = 32;
public static readonly int SharedKeySizeInBytes = 32;

public static void Sign(ArraySegment<byte> signature, ArraySegment<byte> message, ArraySegment<byte> expandedPrivateKey)
{
if (signature.Array == null)
throw new ArgumentNullException("signature.Array");
if (signature.Count != SignatureSizeInBytes)
throw new ArgumentException("signature.Count");
if (expandedPrivateKey.Array == null)
throw new ArgumentNullException("expandedPrivateKey.Array");
if (expandedPrivateKey.Count != ExpandedPrivateKeySizeInBytes)
throw new ArgumentException("expandedPrivateKey.Count");
if (message.Array == null)
throw new ArgumentNullException("message.Array");
Ed25519Operations.crypto_sign2(signature.Array, signature.Offset, message.Array, message.Offset, message.Count, expandedPrivateKey.Array, expandedPrivateKey.Offset);
}

public static byte[] Sign(byte[] message, byte[] expandedPrivateKey)
{
var signature = new byte[SignatureSizeInBytes];
Sign(new ArraySegment<byte>(signature), new ArraySegment<byte>(message), new ArraySegment<byte>(expandedPrivateKey));
return signature;
}

public static void KeyPairFromSeed(out byte[] publicKey, out byte[] expandedPrivateKey, byte[] privateKeySeed)
{
if (privateKeySeed == null)
throw new ArgumentNullException("privateKeySeed");
if (privateKeySeed.Length != PrivateKeySeedSizeInBytes)
throw new ArgumentException("privateKeySeed");
var pk = new byte[PublicKeySizeInBytes];
var sk = new byte[ExpandedPrivateKeySizeInBytes];
Ed25519Operations.crypto_sign_keypair(pk, 0, sk, 0, privateKeySeed, 0);
publicKey = pk;
expandedPrivateKey = sk;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,52 +1,63 @@
namespace Chaos.NaCl.Internal.Ed25519Ref10;
using System;

/*
ge means group element.

Here the group is the set of pairs (x,y) of field elements (see fe.h)
satisfying -x^2 + y^2 = 1 + d x^2y^2
where d = -121665/121666.
namespace Chaos.NaCl.Internal.Ed25519Ref10
{
/*
ge means group element.

Representations:
ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
ge_precomp (Duif): (y+x,y-x,2dxy)
*/
Here the group is the set of pairs (x,y) of field elements (see fe.h)
satisfying -x^2 + y^2 = 1 + d x^2y^2
where d = -121665/121666.

internal struct GroupElementP2
{
public FieldElement X;
public FieldElement Y;
public FieldElement Z;
} ;
Representations:
ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
ge_precomp (Duif): (y+x,y-x,2dxy)
*/

internal struct GroupElementP3
{
public FieldElement X;
public FieldElement Y;
public FieldElement Z;
public FieldElement T;
} ;
internal struct GroupElementP2
{
public FieldElement X;
public FieldElement Y;
public FieldElement Z;
} ;

internal struct GroupElementP1P1
{
public FieldElement X;
public FieldElement Y;
public FieldElement Z;
public FieldElement T;
} ;
internal struct GroupElementP3
{
public FieldElement X;
public FieldElement Y;
public FieldElement Z;
public FieldElement T;
} ;

internal struct GroupElementPreComp
{
public FieldElement yplusx;
public FieldElement yminusx;
public FieldElement xy2d;
internal struct GroupElementP1P1
{
public FieldElement X;
public FieldElement Y;
public FieldElement Z;
public FieldElement T;
} ;

public GroupElementPreComp(FieldElement yplusx, FieldElement yminusx, FieldElement xy2d)
internal struct GroupElementPreComp
{
public FieldElement yplusx;
public FieldElement yminusx;
public FieldElement xy2d;

public GroupElementPreComp(FieldElement yplusx, FieldElement yminusx, FieldElement xy2d)
{
this.yplusx = yplusx;
this.yminusx = yminusx;
this.xy2d = xy2d;
}
} ;

internal struct GroupElementCached
{
this.yplusx = yplusx;
this.yminusx = yminusx;
this.xy2d = xy2d;
}
} ;
public FieldElement YplusX;
public FieldElement YminusX;
public FieldElement Z;
public FieldElement T2d;
} ;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;

namespace Chaos.NaCl.Internal.Ed25519Ref10
{
internal static partial class LookupTables
{
internal static readonly GroupElementPreComp[] Base2 = new GroupElementPreComp[]{
new GroupElementPreComp(
new FieldElement( 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 ),
new FieldElement( -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 ),
new FieldElement( -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 )
),
new GroupElementPreComp(
new FieldElement( 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 ),
new FieldElement( 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 ),
new FieldElement( 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 )
),
new GroupElementPreComp(
new FieldElement( 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 ),
new FieldElement( 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 ),
new FieldElement( 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 )
),
new GroupElementPreComp(
new FieldElement( 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 ),
new FieldElement( -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 ),
new FieldElement( 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 )
),
new GroupElementPreComp(
new FieldElement( -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 ),
new FieldElement( -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 ),
new FieldElement( 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 )
),
new GroupElementPreComp(
new FieldElement( -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 ),
new FieldElement( 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 ),
new FieldElement( 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 )
),
new GroupElementPreComp(
new FieldElement( -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 ),
new FieldElement( -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 ),
new FieldElement( -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 )
),
new GroupElementPreComp(
new FieldElement( -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 ),
new FieldElement( -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 ),
new FieldElement( -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 )
)
};
}
}
Loading
Loading