30
30
#include < Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.h>
31
31
#include < BleLayer/WeaveBleServiceData.h>
32
32
#include < Weave/Support/Base64.h>
33
+ #include < Weave/Profiles/security/WeavePrivateKey.h>
33
34
34
35
#if WEAVE_DEVICE_CONFIG_ENABLE_THREAD
35
36
#include < Weave/DeviceLayer/ThreadStackManager.h>
@@ -53,7 +54,6 @@ WEAVE_ERROR GenericConfigurationManagerImpl<ImplClass>::_Init()
53
54
SetFlag (mFlags , kFlag_IsServiceProvisioned , Impl ()->ConfigValueExists (ImplClass::kConfigKey_ServiceConfig ));
54
55
SetFlag (mFlags , kFlag_IsMemberOfFabric , Impl ()->ConfigValueExists (ImplClass::kConfigKey_FabricId ));
55
56
SetFlag (mFlags , kFlag_IsPairedToAccount , Impl ()->ConfigValueExists (ImplClass::kConfigKey_PairedAccountId ));
56
- SetFlag (mFlags , kFlag_OperationalDeviceCredentialsProvisioned , Impl ()->ConfigValueExists (ImplClass::kConfigKey_OperationalDeviceCert ));
57
57
58
58
return WEAVE_NO_ERROR;
59
59
}
@@ -502,26 +502,19 @@ WEAVE_ERROR GenericConfigurationManagerImpl<ImplClass>::_StoreDevicePrivateKey(c
502
502
}
503
503
504
504
template <class ImplClass >
505
- WEAVE_ERROR GenericConfigurationManagerImpl<ImplClass>::_ClearOperationalDeviceCredentials (void )
505
+ bool GenericConfigurationManagerImpl<ImplClass>::_OperationalDeviceIdProvisioned (void )
506
506
{
507
- Impl ()->ClearConfigValue (ImplClass::kConfigKey_OperationalDeviceId );
508
- Impl ()->ClearConfigValue (ImplClass::kConfigKey_OperationalDeviceCert );
509
- Impl ()->ClearConfigValue (ImplClass::kConfigKey_OperationalDeviceICACerts );
510
- Impl ()->ClearConfigValue (ImplClass::kConfigKey_OperationalDevicePrivateKey );
511
-
512
- ClearFlag (mFlags , kFlag_OperationalDeviceCredentialsProvisioned );
513
-
514
- return WEAVE_NO_ERROR;
507
+ return Impl ()->ConfigValueExists (ImplClass::kConfigKey_OperationalDeviceId );
515
508
}
516
509
517
510
template <class ImplClass >
518
- bool GenericConfigurationManagerImpl<ImplClass>::_OperationalDeviceCredentialsProvisioned( )
511
+ bool GenericConfigurationManagerImpl<ImplClass>::_OperationalDeviceCertAndPrivateKeyProvisioned( void )
519
512
{
520
- return :: nl::GetFlag ( mFlags , kFlag_OperationalDeviceCredentialsProvisioned );
513
+ return Impl ()-> ConfigValueExists (ImplClass:: kConfigKey_OperationalDeviceCert );
521
514
}
522
515
523
516
template <class ImplClass >
524
- bool GenericConfigurationManagerImpl<ImplClass>::UseManufacturerCredentialsAsOperational()
517
+ bool GenericConfigurationManagerImpl<ImplClass>::UseManufacturerCredentialsAsOperational(void )
525
518
{
526
519
return ::nl::GetFlag (mFlags , kFlag_UseManufacturerCredentialsAsOperational );
527
520
}
@@ -532,6 +525,132 @@ void GenericConfigurationManagerImpl<ImplClass>::_UseManufacturerCredentialsAsOp
532
525
SetFlag (mFlags , kFlag_UseManufacturerCredentialsAsOperational , val);
533
526
}
534
527
528
+ static WEAVE_ERROR GenerateOperationalECDSASignature (const uint8_t *hash, uint8_t hashLen, EncodedECDSASignature& ecdsaSig)
529
+ {
530
+ WEAVE_ERROR err;
531
+ uint8_t * weavePrivKey = NULL ;
532
+ size_t weavePrivKeyLen;
533
+ uint32_t weaveCurveId;
534
+ EncodedECPublicKey pubKey;
535
+ EncodedECPrivateKey privKey;
536
+
537
+ // Determine the length of the private key.
538
+ err = ConfigurationMgr ().GetDevicePrivateKey ((uint8_t *)NULL , 0 , weavePrivKeyLen);
539
+ SuccessOrExit (err);
540
+
541
+ // Fail if no private key has been configured.
542
+ VerifyOrExit (weavePrivKeyLen != 0 , err = WEAVE_ERROR_KEY_NOT_FOUND);
543
+
544
+ // Create a temporary buffer to hold the private key.
545
+ weavePrivKey = (uint8_t *)Platform::Security::MemoryAlloc (weavePrivKeyLen);
546
+ VerifyOrExit (weavePrivKey != NULL , err = WEAVE_ERROR_NO_MEMORY);
547
+
548
+ // Read the private key.
549
+ err = ConfigurationMgr ().GetDevicePrivateKey (weavePrivKey, weavePrivKeyLen, weavePrivKeyLen);
550
+ SuccessOrExit (err);
551
+
552
+ // Decode operational device private/public keys from private key TLV structure.
553
+ err = Profiles::Security::DecodeWeaveECPrivateKey (weavePrivKey, weavePrivKeyLen, weaveCurveId, pubKey, privKey);
554
+ SuccessOrExit (err);
555
+
556
+ // Generate operational device signature.
557
+ err = nl::Weave::Crypto::GenerateECDSASignature (Profiles::Security::WeaveCurveIdToOID (weaveCurveId),
558
+ hash, hashLen, privKey, ecdsaSig);
559
+ SuccessOrExit (err);
560
+
561
+ exit:
562
+ if (weavePrivKey != NULL )
563
+ {
564
+ Platform::Security::MemoryFree (weavePrivKey);
565
+ }
566
+ return err;
567
+ }
568
+
569
+ template <class ImplClass >
570
+ WEAVE_ERROR GenericConfigurationManagerImpl<ImplClass>::_GenerateAndStoreOperationalDeviceId(void )
571
+ {
572
+ WEAVE_ERROR err;
573
+ uint64_t deviceId;
574
+
575
+ // Generate random device Id.
576
+ err = GenerateWeaveNodeId (deviceId);
577
+ SuccessOrExit (err);
578
+
579
+ // Store generated device Id.
580
+ err = _StoreDeviceId (deviceId);
581
+ SuccessOrExit (err);
582
+
583
+ exit:
584
+ if (err != WEAVE_NO_ERROR)
585
+ {
586
+ Impl ()->ClearConfigValue (ImplClass::kConfigKey_OperationalDeviceId );
587
+ }
588
+ return err;
589
+ }
590
+
591
+ template <class ImplClass >
592
+ WEAVE_ERROR GenericConfigurationManagerImpl<ImplClass>::_GenerateAndStoreOperationalDeviceCertAndPrivateKey(void )
593
+ {
594
+ enum
595
+ {
596
+ kWeaveDeviceCertBufSize = 300 , // Size of buffer needed to hold Weave device certificate.
597
+ kWeaveDevicePrivateKeyBufSize = 128 , // Size of buffer needed to hold Weave device private key.
598
+ };
599
+
600
+ WEAVE_ERROR err;
601
+ uint64_t deviceId;
602
+ uint8_t weavePrivKey[kWeaveDevicePrivateKeyBufSize ];
603
+ uint32_t weavePrivKeyLen;
604
+ uint8_t weaveCert[kWeaveDeviceCertBufSize ];
605
+ uint16_t weaveCertLen;
606
+ uint8_t privKeyBuf[EncodedECPrivateKey::kMaxValueLength ];
607
+ uint8_t pubKeyBuf[EncodedECPublicKey::kMaxValueLength ];
608
+ EncodedECPublicKey pubKey;
609
+ EncodedECPrivateKey privKey;
610
+
611
+ // Clear intermediate CA certificate if it was provisioned.
612
+ Impl ()->ClearConfigValue (ImplClass::kConfigKey_OperationalDeviceICACerts );
613
+
614
+ // Get operational device Id.
615
+ err = _GetDeviceId (deviceId);
616
+ SuccessOrExit (err);
617
+
618
+ privKey.PrivKey = privKeyBuf;
619
+ privKey.PrivKeyLen = sizeof (privKeyBuf);
620
+
621
+ pubKey.ECPoint = pubKeyBuf;
622
+ pubKey.ECPointLen = sizeof (pubKeyBuf);
623
+
624
+ // Generate random EC private/public key pair.
625
+ err = GenerateECDHKey (Profiles::Security::WeaveCurveIdToOID (WEAVE_CONFIG_OPERATIONAL_DEVICE_CERT_CURVE_ID), pubKey, privKey);
626
+ SuccessOrExit (err);
627
+
628
+ // Encode Weave device EC private/public key pair into EllipticCurvePrivateKey TLV structure.
629
+ err = EncodeWeaveECPrivateKey (WEAVE_CONFIG_OPERATIONAL_DEVICE_CERT_CURVE_ID, &pubKey, privKey,
630
+ weavePrivKey, sizeof (weavePrivKey), weavePrivKeyLen);
631
+ SuccessOrExit (err);
632
+
633
+ // Store generated operational device private key.
634
+ err = _StoreDevicePrivateKey (weavePrivKey, weavePrivKeyLen);
635
+ SuccessOrExit (err);
636
+
637
+ // Generate self-signed operational device certificate.
638
+ err = Profiles::Security::GenerateOperationalDeviceCert (deviceId, pubKey, weaveCert, sizeof (weaveCert), weaveCertLen, GenerateOperationalECDSASignature);
639
+ SuccessOrExit (err);
640
+
641
+ // Store generated operational device certificate.
642
+ err = _StoreDeviceCertificate (weaveCert, weaveCertLen);
643
+ SuccessOrExit (err);
644
+
645
+ exit:
646
+ if (err != WEAVE_NO_ERROR)
647
+ {
648
+ Impl ()->ClearConfigValue (ImplClass::kConfigKey_OperationalDeviceCert );
649
+ Impl ()->ClearConfigValue (ImplClass::kConfigKey_OperationalDevicePrivateKey );
650
+ }
651
+ return err;
652
+ }
653
+
535
654
#endif // WEAVE_DEVICE_CONFIG_ENABLE_JUST_IN_TIME_PROVISIONING
536
655
537
656
template <class ImplClass >
@@ -666,6 +785,14 @@ WEAVE_ERROR GenericConfigurationManagerImpl<ImplClass>::_ClearServiceProvisionin
666
785
Impl ()->ClearConfigValue (ImplClass::kConfigKey_ServiceConfig );
667
786
Impl ()->ClearConfigValue (ImplClass::kConfigKey_PairedAccountId );
668
787
788
+ #if WEAVE_DEVICE_CONFIG_ENABLE_JUST_IN_TIME_PROVISIONING
789
+ // If necessary, generate new operational device credentials (certificate and private key).
790
+ if (_IsPairedToAccount () || _IsServiceProvisioned ())
791
+ {
792
+ _GenerateAndStoreOperationalDeviceCertAndPrivateKey ();
793
+ }
794
+ #endif
795
+
669
796
// TODO: Move these behaviors out of configuration manager.
670
797
671
798
// If necessary, post an event alerting other subsystems to the change in
@@ -899,7 +1026,7 @@ bool GenericConfigurationManagerImpl<ImplClass>::_IsFullyProvisioned()
899
1026
Impl ()->IsPairedToAccount () &&
900
1027
#endif
901
1028
#if WEAVE_DEVICE_CONFIG_ENABLE_JUST_IN_TIME_PROVISIONING
902
- (!UseManufacturerCredentialsAsOperational () && _OperationalDeviceCredentialsProvisioned ()) &&
1029
+ (!UseManufacturerCredentialsAsOperational () && _OperationalDeviceCertAndPrivateKeyProvisioned ()) &&
903
1030
#endif
904
1031
Impl ()->IsMemberOfFabric ();
905
1032
}
0 commit comments