Пример #1
0
        /// <summary>
        /// Creates a certificate using the vendor/root key containing the challengeCommonName as the
        /// subject.  Proof-of-possession of the vendor/root key is required to enroll a root certificate
        /// with the Azure Device Provisioning Service.
        /// </summary>
        /// <param name="">The challenge common name "nonce"</param>
        /// <returns>The signed challengeCommonName</returns>
        public static string CreateDevIDPoP(DeviceAuthBundle bundle, string challengeCommonName)
        {
            rDeviceCertSubject = new X509Name(challengeCommonName);
            var rootKey             = new AsymmetricCipherKeyPair(bundle.RootCredential.PubKey, bundle.RootCredential.PrivKey);
            var rootSigningSeed     = Hash(Hash(rR00t));
            var challengePoPCert    = CreateDeviceCert(rootKey, bundle.DeviceIDCredential.PubKey, rootSigningSeed);
            var challengePoPCertPEM = DerToPem("CERTIFICATE", challengePoPCert);

            return(challengePoPCertPEM);
        }
Пример #2
0
        /// <summary>
        /// Create keys and certificates
        /// </summary>
        /// <param name="uds">Per-device Unique Device Secret</param>
        /// <param name="fwid">Hash of firmware</param>
        /// <returns>The keys and certificates for the device</returns>
        public static DeviceAuthBundle CreateDeviceAuthBundle(byte[] uds, byte[] fwid)
        {
            if ((uds.Length != 32) || (fwid.Length != 32))
            {
                throw new ArgumentException("UDS and FWID must be 32-bytes in length");
            }

            DeviceAuthBundle authBundle = new DeviceAuthBundle();

            // In a real (non-emulated) DICE system, the CDI (compound device identity) would be
            // created by the SoC at startup, or calculated by ROM-based code very early in boot.
            // Here we simulate CDI creation based on a seed (the UDS, or Unique Device Secret)
            // provided by the caller.
            byte[] cdi = DICE.GetCDI(uds, rDigest);

            // Real DICE/RIoT Systems create keys and certificates on boot based on seeds.  The seeds
            // can change on various sorts of software update, but otherwise the keys and certificates
            // remain the same.
            rootSeed  = Hash(rR00t);
            devIdSeed = Hash(cdi);
            aliasSeed = Hash(devIdSeed, fwid);

            // Vendor CA root key
            var rootKey = DeriveEccKey(rootSeed);

            // DeviceID key (should never change, but should be different for each device)
            var deviceID = DeriveEccKey(devIdSeed);

            // Device GUID (should never change, but should be different for each device)
            var deviceGuid = DeriveGuid(devIdSeed);

            // Alias key (will change on firmware update - i.e. when FWID changes)
            var aliasKey = DeriveEccKey(aliasSeed);

            // If the device or alias cert subjects contain the string "guid" replace with the per-device
            // GUID just calculated
            if (rAliasCertSubject.ToString().Contains("guid"))
            {
                rAliasCertSubject = new X509Name(rAliasCertSubject.ToString().Replace("guid", deviceGuid.ToString()));
            }

            if (rDeviceCertSubject.ToString().Contains("guid"))
            {
                rDeviceCertSubject = new X509Name(rDeviceCertSubject.ToString().Replace("guid", deviceGuid.ToString()));
            }

            // Create the self-signed root CA certificate
            X509Certificate rootCert = CreateRootCert(rootKey, rootSeed);

            // Create the DeviceID certificate signed by the root vendor CA
            X509Certificate devCert = CreateDeviceCert(rootKey, deviceID.Public, rootSeed);

            // Create the self-signed DeviceID certificate
            X509Certificate devCertSelfSigned = CreateSelfSignedDeviceCert(deviceID, devIdSeed);

            // Create the Alias Key certificate signed by the deviceID key
            X509Certificate aliasCert = CreateAliasCert(deviceID, aliasKey, fwid, devIdSeed);

            // Create a PKCS10 Certificate Signing Request (CSR) for the deviceId
            var deviceIdCsr = CreateCsr(deviceID, devIdSeed);

            // Create return structure containing the keys and certificates just created
            authBundle.RootCredential = new CredentialBundle
            {
                PubKey    = rootKey.Public,
                PubKeyPem = DerToPem("PUBLIC KEY", rootKey.Public),
                PrivKey   = rootKey.Private,
                Cert      = rootCert,
                CertPem   = DerToPem("CERTIFICATE", rootCert)
            };
            authBundle.DeviceIDCredential = new CredentialBundle
            {
                PubKey    = deviceID.Public,
                PubKeyPem = DerToPem("PUBLIC KEY", deviceID.Public),
                Cert      = devCert,
                CertPem   = DerToPem("CERTIFICATE", devCert)
            };
            authBundle.SelfSignedDeviceIDCredential = new CredentialBundle
            {
                PubKey    = deviceID.Public,
                PubKeyPem = DerToPem("PUBLIC KEY", deviceID.Public),
                Cert      = devCertSelfSigned,
                CertPem   = DerToPem("CERTIFICATE", devCertSelfSigned)
            };
            authBundle.AliasCredential = new CredentialBundle
            {
                PubKey     = aliasKey.Public,
                PubKeyPem  = DerToPem("PUBLIC KEY", aliasKey.Public),
                PrivKey    = aliasKey.Private,
                PrivKeyPem = DerToPem("PRIVATE KEY", aliasKey.Private),
                Cert       = aliasCert,
                CertPem    = DerToPem("CERTIFICATE", aliasCert)
            };

            authBundle.Csr = new CsrBundle
            {
                Csr    = deviceIdCsr,
                CsrPem = DerToPem("NEW CERTIFICATE REQUEST", deviceIdCsr)
            };

            return(authBundle);
        }