@@ -164,12 +164,18 @@ public static void AssertEvaluationLicense()
164
164
165
165
private static readonly int [ ] revokedSubs = { 4018 , 4019 , 4041 , 4331 , 4581 } ;
166
166
167
- private static LicenseKey __activatedLicense ;
167
+ private class __ActivatedLicense
168
+ {
169
+ internal readonly LicenseKey LicenseKey ;
170
+ internal __ActivatedLicense ( LicenseKey licenseKey ) => LicenseKey = licenseKey ;
171
+ }
172
+
173
+ private static __ActivatedLicense __activatedLicense ;
168
174
public static void RegisterLicense ( string licenseKeyText )
169
175
{
170
176
JsConfig . InitStatics ( ) ;
171
177
172
- if ( __activatedLicense != null ) //Skip multple license registrations. Use RemoveLicense() to reset.
178
+ if ( __activatedLicense != null ) //Skip multiple license registrations. Use RemoveLicense() to reset.
173
179
return ;
174
180
175
181
string subId = null ;
@@ -183,7 +189,7 @@ public static void RegisterLicense(string licenseKeyText)
183
189
if ( int . TryParse ( subId , out var subIdInt ) && revokedSubs . Contains ( subIdInt ) )
184
190
throw new LicenseException ( "This subscription has been revoked. " + ContactDetails ) ;
185
191
186
- var key = PclExport . Instance . VerifyLicenseKeyText ( licenseKeyText ) ;
192
+ var key = VerifyLicenseKeyText ( licenseKeyText ) ;
187
193
ValidateLicenseKey ( key ) ;
188
194
}
189
195
catch ( Exception ex )
@@ -226,7 +232,7 @@ private static void ValidateLicenseKey(LicenseKey key)
226
232
if ( key . Type == LicenseType . Trial && DateTime . UtcNow > key . Expiry )
227
233
throw new LicenseException ( $ "This trial license has expired on { key . Expiry : d} ." + ContactDetails ) . Trace ( ) ;
228
234
229
- __activatedLicense = key ;
235
+ __activatedLicense = new __ActivatedLicense ( key ) ;
230
236
}
231
237
232
238
public static void RemoveLicense ( )
@@ -236,7 +242,7 @@ public static void RemoveLicense()
236
242
237
243
public static LicenseFeature ActivatedLicenseFeatures ( )
238
244
{
239
- return __activatedLicense != null ? __activatedLicense . GetLicensedFeatures ( ) : LicenseFeature . None ;
245
+ return __activatedLicense ? . LicenseKey . GetLicensedFeatures ( ) ?? LicenseFeature . None ;
240
246
}
241
247
242
248
public static void ApprovedUsage ( LicenseFeature licenseFeature , LicenseFeature requestedFeature ,
@@ -423,12 +429,192 @@ public static string GetHashKeyToSign(this LicenseKey key)
423
429
424
430
public static Exception GetInnerMostException ( this Exception ex )
425
431
{
426
- //Extract true exception from static intializers (e.g. LicenseException)
432
+ //Extract true exception from static initializers (e.g. LicenseException)
427
433
while ( ex . InnerException != null )
428
434
{
429
435
ex = ex . InnerException ;
430
436
}
431
437
return ex ;
432
438
}
439
+
440
+ //License Utils
441
+ public static bool VerifySignedHash ( byte [ ] DataToVerify , byte [ ] SignedData , System . Security . Cryptography . RSAParameters Key )
442
+ {
443
+ try
444
+ {
445
+ var RSAalg = new System . Security . Cryptography . RSACryptoServiceProvider ( ) ;
446
+ RSAalg . ImportParameters ( Key ) ;
447
+ return RSAalg . VerifySha1Data ( DataToVerify , SignedData ) ;
448
+
449
+ }
450
+ catch ( System . Security . Cryptography . CryptographicException ex )
451
+ {
452
+ Tracer . Instance . WriteError ( ex ) ;
453
+ return false ;
454
+ }
455
+ }
456
+
457
+ public static LicenseKey VerifyLicenseKeyText ( string licenseKeyText )
458
+ {
459
+ #if NET45 || NETCORE2_1
460
+ LicenseKey key ;
461
+ try
462
+ {
463
+ if ( ! licenseKeyText . VerifyLicenseKeyText ( out key ) )
464
+ throw new ArgumentException ( "licenseKeyText" ) ;
465
+ }
466
+ catch ( Exception e )
467
+ {
468
+ if ( ! VerifyLicenseKeyTextFallback ( licenseKeyText , out key ) )
469
+ throw ;
470
+ }
471
+ return key ;
472
+ #else
473
+ return licenseKeyText . ToLicenseKey ( ) ;
474
+ #endif
475
+ }
476
+
477
+ private static void FromXml ( this System . Security . Cryptography . RSA rsa , string xml )
478
+ {
479
+ #if NET45
480
+ rsa . FromXmlString ( xml ) ;
481
+ #else
482
+ //throws PlatformNotSupportedException
483
+ var csp = ExtractFromXml ( xml ) ;
484
+ rsa . ImportParameters ( csp ) ;
485
+ #endif
486
+ }
487
+
488
+ #if ! NET45
489
+ private static System . Security . Cryptography . RSAParameters ExtractFromXml ( string xml )
490
+ {
491
+ var csp = new System . Security . Cryptography . RSAParameters ( ) ;
492
+ using ( var reader = System . Xml . XmlReader . Create ( new StringReader ( xml ) ) )
493
+ {
494
+ while ( reader . Read ( ) )
495
+ {
496
+ if ( reader . NodeType != System . Xml . XmlNodeType . Element )
497
+ continue ;
498
+
499
+ var elName = reader . Name ;
500
+ if ( elName == "RSAKeyValue" )
501
+ continue ;
502
+
503
+ do {
504
+ reader . Read ( ) ;
505
+ } while ( reader . NodeType != System . Xml . XmlNodeType . Text && reader . NodeType != System . Xml . XmlNodeType . EndElement ) ;
506
+
507
+ if ( reader . NodeType == System . Xml . XmlNodeType . EndElement )
508
+ continue ;
509
+
510
+ var value = reader . Value ;
511
+ switch ( elName )
512
+ {
513
+ case "Modulus" :
514
+ csp . Modulus = Convert . FromBase64String ( value ) ;
515
+ break ;
516
+ case "Exponent" :
517
+ csp . Exponent = Convert . FromBase64String ( value ) ;
518
+ break ;
519
+ case "P" :
520
+ csp . P = Convert . FromBase64String ( value ) ;
521
+ break ;
522
+ case "Q" :
523
+ csp . Q = Convert . FromBase64String ( value ) ;
524
+ break ;
525
+ case "DP" :
526
+ csp . DP = Convert . FromBase64String ( value ) ;
527
+ break ;
528
+ case "DQ" :
529
+ csp . DQ = Convert . FromBase64String ( value ) ;
530
+ break ;
531
+ case "InverseQ" :
532
+ csp . InverseQ = Convert . FromBase64String ( value ) ;
533
+ break ;
534
+ case "D" :
535
+ csp . D = Convert . FromBase64String ( value ) ;
536
+ break ;
537
+ }
538
+ }
539
+
540
+ return csp ;
541
+ }
542
+ }
543
+ #endif
544
+
545
+ public static bool VerifyLicenseKeyText ( this string licenseKeyText , out LicenseKey key )
546
+ {
547
+ var publicRsaProvider = new System . Security . Cryptography . RSACryptoServiceProvider ( ) ;
548
+ publicRsaProvider . FromXml ( LicenseUtils . LicensePublicKey ) ;
549
+ var publicKeyParams = publicRsaProvider . ExportParameters ( false ) ;
550
+
551
+ key = licenseKeyText . ToLicenseKey ( ) ;
552
+ var originalData = key . GetHashKeyToSign ( ) . ToUtf8Bytes ( ) ;
553
+ var signedData = Convert . FromBase64String ( key . Hash ) ;
554
+
555
+ return VerifySignedHash ( originalData , signedData , publicKeyParams ) ;
556
+ }
557
+
558
+ public static bool VerifyLicenseKeyTextFallback ( this string licenseKeyText , out LicenseKey key )
559
+ {
560
+ System . Security . Cryptography . RSAParameters publicKeyParams ;
561
+ try
562
+ {
563
+ var publicRsaProvider = new System . Security . Cryptography . RSACryptoServiceProvider ( ) ;
564
+ publicRsaProvider . FromXml ( LicenseUtils . LicensePublicKey ) ;
565
+ publicKeyParams = publicRsaProvider . ExportParameters ( false ) ;
566
+ }
567
+ catch ( Exception ex )
568
+ {
569
+ throw new Exception ( "Could not import LicensePublicKey" , ex ) ;
570
+ }
571
+
572
+ try
573
+ {
574
+ key = licenseKeyText . ToLicenseKeyFallback ( ) ;
575
+ }
576
+ catch ( Exception ex )
577
+ {
578
+ throw new Exception ( "Could not deserialize LicenseKeyText Manually" , ex ) ;
579
+ }
580
+
581
+ byte [ ] originalData ;
582
+ byte [ ] signedData ;
583
+
584
+ try
585
+ {
586
+ originalData = key . GetHashKeyToSign ( ) . ToUtf8Bytes ( ) ;
587
+ }
588
+ catch ( Exception ex )
589
+ {
590
+ throw new Exception ( "Could not convert HashKey to UTF-8" , ex ) ;
591
+ }
592
+
593
+ try
594
+ {
595
+ signedData = Convert . FromBase64String ( key . Hash ) ;
596
+ }
597
+ catch ( Exception ex )
598
+ {
599
+ throw new Exception ( "Could not convert key.Hash from Base64" , ex ) ;
600
+ }
601
+
602
+ try
603
+ {
604
+ return VerifySignedHash ( originalData , signedData , publicKeyParams ) ;
605
+ }
606
+ catch ( Exception ex )
607
+ {
608
+ throw new Exception ( $ "Could not Verify License Key ({ originalData . Length } , { signedData . Length } )", ex ) ;
609
+ }
610
+ }
611
+
612
+ public static bool VerifySha1Data ( this System . Security . Cryptography . RSACryptoServiceProvider RSAalg , byte [ ] unsignedData , byte [ ] encryptedData )
613
+ {
614
+ using ( var sha = new System . Security . Cryptography . SHA1CryptoServiceProvider ( ) )
615
+ {
616
+ return RSAalg . VerifyData ( unsignedData , sha , encryptedData ) ;
617
+ }
618
+ }
433
619
}
434
620
}
0 commit comments