/// <summary>
        /// Create a notification endpoint object in asynchronous mode.
        /// </summary>
        /// <param name="name">Name of notification endpoint</param>
        /// <param name="endPointType">Notification endpoint type</param>
        /// <param name="endPointAddress">Notification endpoint address</param>
        /// <param name="credential"></param>
        /// <returns>Task of creating notification endpoint.</returns>
        public Task <INotificationEndPoint> CreateAsync(string name, NotificationEndPointType endPointType,
                                                        string endPointAddress, byte[] credential)
        {
            if (credential == null || credential.Length == 0)
            {
                throw new ArgumentNullException("credential");
            }

            if (endPointType != NotificationEndPointType.WebHook)
            {
                throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, StringTable.SupportWebHookWithCredentialOnly, "endPointType"));
            }

            IMediaDataServiceContext dataContext =
                this.MediaContext.MediaServicesClassFactory.CreateDataServiceContext();

            string protectionKeyId = ContentKeyBaseCollection.GetProtectionKeyIdForContentKey(MediaContext,
                                                                                              ContentKeyType.ConfigurationEncryption);
            X509Certificate2 certToUse = ContentKeyBaseCollection.GetCertificateForProtectionKeyId(MediaContext, protectionKeyId);

            byte[] encryptedContentKey = EncryptionUtils.EncryptSymmetricKeyData(certToUse, credential);

            NotificationEndPoint notificationEndPoint = new NotificationEndPoint
            {
                Name                        = name,
                EndPointType                = (int)endPointType,
                EndPointAddress             = endPointAddress,
                CredentialType              = (int)NotificationEndPointCredentialType.SigningKey,
                EncryptedEndPointCredential = Convert.ToBase64String(encryptedContentKey),
                ProtectionKeyType           = (int)ProtectionKeyType.X509CertificateThumbprint,
                ProtectionKeyId             = protectionKeyId
            };

            notificationEndPoint.SetMediaContext(MediaContext);
            dataContext.AddObject(NotificationEndPoints, notificationEndPoint);

            MediaRetryPolicy retryPolicy =
                this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter);

            return(retryPolicy.ExecuteAsync <IMediaDataServiceResponse>(
                       () => dataContext.SaveChangesAsync(notificationEndPoint))
                   .ContinueWith <INotificationEndPoint>(
                       t =>
            {
                t.ThrowIfFaulted();

                return (NotificationEndPoint)t.Result.AsyncState;
            },
                       TaskContinuationOptions.ExecuteSynchronously));
        }
        /// <summary>
        /// Creates the common content key.
        /// </summary>
        /// <param name="keyId">The key id.</param>
        /// <param name="contentKey">The content key data.</param>
        /// <param name="name">The name.</param>
        /// <param name="cert">The cert.</param>
        /// <returns>The content key.</returns>
        internal static ContentKeyData CreateCommonContentKey(Guid keyId, byte[] contentKey, string name, X509Certificate2 cert)
        {
            byte[] encryptedContentKey = CommonEncryption.EncryptContentKeyToCertificate(cert, contentKey);

            ContentKeyData contentKeyData = new ContentKeyData
            {
                Id = EncryptionUtils.GetKeyIdentifierAsString(keyId),
                EncryptedContentKey = Convert.ToBase64String(encryptedContentKey),
                ContentKeyType      = (int)ContentKeyType.CommonEncryption,
                ProtectionKeyId     = cert.Thumbprint,
                ProtectionKeyType   = (int)ProtectionKeyType.X509CertificateThumbprint,
                Name     = name,
                Checksum = EncryptionUtils.CalculateChecksum(contentKey, keyId)
            };

            return(contentKeyData);
        }
Example #3
0
        private FileEncryption GetFileEncryption()
        {
            if (!this.IsEncrypted)
            {
                return(null);
            }

            // We want to support downloading PlayReady encrypted content too.
            if (this.EncryptionScheme != FileEncryption.SchemeName)
            {
                return(null);
            }

            IContentKey key   = this.Asset.ContentKeys.Where(c => c.ContentKeyType == ContentKeyType.StorageEncryption).FirstOrDefault();
            Guid        keyId = EncryptionUtils.GetKeyIdAsGuid(key.Id);

            return(new FileEncryption(key.GetClearKeyValue(), keyId));
        }
Example #4
0
        /// <summary>
        /// Creates FairPlay Pfx Password.
        /// </summary>
        /// <param name="keyId">The key id.</param>
        /// <param name="contentKey">The content key data.</param>
        /// <param name="name">The name.</param>
        /// <param name="cert">The cert.</param>
        /// <returns>The content key.</returns>
        internal static ContentKeyData InitializeFairPlayPfxPassword(Guid keyId, byte[] contentKey, string name, X509Certificate2 cert)
        {
            RSACryptoServiceProvider rsaPublicKey = cert.PublicKey.Key as RSACryptoServiceProvider;

            RSAOAEPKeyExchangeFormatter keyFormatter = new RSAOAEPKeyExchangeFormatter(rsaPublicKey);

            byte[] encryptedContentKey = keyFormatter.CreateKeyExchange(contentKey);

            ContentKeyData contentKeyData = new ContentKeyData
            {
                Id = EncryptionUtils.GetKeyIdentifierAsString(keyId),
                EncryptedContentKey = Convert.ToBase64String(encryptedContentKey),
                ContentKeyType      = (int)ContentKeyType.FairPlayPfxPassword,
                ProtectionKeyId     = cert.Thumbprint,
                ProtectionKeyType   = (int)ProtectionKeyType.X509CertificateThumbprint,
                Name = name,
            };

            return(contentKeyData);
        }
        /// <summary>
        /// Gets the certificate for protection key id.
        /// </summary>
        /// <param name="dataContext">The data context.</param>
        /// <param name="protectionKeyId">The protection key id.</param>
        /// <returns>The content key.</returns>
        internal static X509Certificate2 GetCertificateForProtectionKeyId(DataServiceContext dataContext, string protectionKeyId)
        {
            // First check to see if we have the cert in our store already.
            X509Certificate2 certToUse = EncryptionUtils.GetCertificateFromStore(protectionKeyId);

            if ((certToUse == null) && (dataContext != null))
            {
                // If not, download it from Nimbus to use.
                Uri uriGetProtectionKey       = new Uri(string.Format(CultureInfo.InvariantCulture, "/GetProtectionKey?protectionKeyId='{0}'", protectionKeyId), UriKind.Relative);
                IEnumerable <string> results2 = dataContext.Execute <string>(uriGetProtectionKey);
                string certString             = results2.Single();

                byte[] certBytes = Convert.FromBase64String(certString);
                certToUse = new X509Certificate2(certBytes);

                // Finally save it for next time.
                EncryptionUtils.SaveCertificateToStore(certToUse);
            }

            return(certToUse);
        }
Example #6
0
        /// <summary>
        /// Decrypts the configuration string.
        /// </summary>
        /// <param name="cloudMediaContext">The cloud media context.</param>
        /// <param name="encryptionKeyId">The encryption key id.</param>
        /// <param name="initializationVector">The initialization vector.</param>
        /// <param name="encryptedConfiguration">The encrypted configuration.</param>
        /// <returns>The decrypted configuration.</returns>
        internal static string DecryptConfigurationString(CloudMediaContext cloudMediaContext, string encryptionKeyId, string initializationVector, string encryptedConfiguration)
        {
            if (cloudMediaContext == null)
            {
                throw new ArgumentNullException("cloudMediaContext");
            }

            if (string.IsNullOrEmpty(encryptionKeyId))
            {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, StringTable.ErrorArgCannotBeNullOrEmpty, "encryption key identifier"), "encryptionKeyId");
            }

            if (string.IsNullOrEmpty(initializationVector))
            {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, StringTable.ErrorArgCannotBeNullOrEmpty, "initialization vector"), "initializationVector");
            }

            if (string.IsNullOrEmpty(encryptedConfiguration))
            {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, StringTable.ErrorArgCannotBeNullOrEmpty, "encrypted configuration"), "encryptedConfiguration");
            }

            string returnValue;
            Guid   keyId = EncryptionUtils.GetKeyIdAsGuid(encryptionKeyId);

            byte[] iv = Convert.FromBase64String(initializationVector);

            IContentKey configKey = cloudMediaContext.ContentKeys.Where(c => c.Id == encryptionKeyId).Single();

            byte[] contentKey = configKey.GetClearKeyValue();

            using (ConfigurationEncryption configEnc = new ConfigurationEncryption(keyId, contentKey, iv))
            {
                returnValue = configEnc.Decrypt(encryptedConfiguration);
            }

            return(returnValue);
        }
Example #7
0
 /// <summary>
 /// Gets the checksum.
 /// </summary>
 /// <returns>The checksum.</returns>
 public string GetChecksum()
 {
     return(EncryptionUtils.CalculateChecksum(this._key.Key, this.KeyIdentifier));
 }
Example #8
0
 /// <summary>
 /// Gets the key identifier as string.
 /// </summary>
 /// <returns>The key ID.</returns>
 public string GetKeyIdentifierAsString()
 {
     return(EncryptionUtils.GetKeyIdentifierAsString(this.KeyIdentifier));
 }
Example #9
0
 /// <summary>
 /// Encrypts the content key to certificate.
 /// </summary>
 /// <param name="certToUse">The cert to use.</param>
 /// <returns>The encrypted content key.</returns>
 public byte[] EncryptContentKeyToCertificate(X509Certificate2 certToUse)
 {
     return(EncryptionUtils.EncryptSymmetricKey(certToUse, this._key));
 }
Example #10
0
        /// <summary>
        /// Uploads the destinationPath with given path asynchronously
        /// </summary>
        /// <param name="path">The path of a destinationPath to upload</param>
        /// <param name="blobTransferClient">The <see cref="BlobTransferClient"/> which is used to upload files.</param>
        /// <param name="locator">An asset <see cref="ILocator"/> which defines permissions associated with the Asset.</param>
        /// <param name="token">A <see cref="CancellationToken"/> to use for canceling upload operation.</param>
        /// <returns>A function delegate that returns the future result to be available through the Task.</returns>
        public Task UploadAsync(string path, BlobTransferClient blobTransferClient, ILocator locator, CancellationToken token)
        {
            if (blobTransferClient == null)
            {
                throw new ArgumentNullException("blobTransferClient");
            }

            if (locator == null)
            {
                throw new ArgumentNullException("locator");
            }

            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            if (!File.Exists(path))
            {
                throw new FileNotFoundException(path);
            }

            ValidateFileName(path);

            IContentKey          contentKeyData       = null;
            FileEncryption       fileEncryption       = null;
            AssetCreationOptions assetCreationOptions = this.Asset.Options;

            if (assetCreationOptions.HasFlag(AssetCreationOptions.StorageEncrypted))
            {
                contentKeyData = this.Asset.ContentKeys.Where(c => c.ContentKeyType == ContentKeyType.StorageEncryption).FirstOrDefault();
                if (contentKeyData == null)
                {
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, StringTable.StorageEncryptionContentKeyIsMissing, this.Asset.Id));
                }

                fileEncryption = new FileEncryption(contentKeyData.GetClearKeyValue(), EncryptionUtils.GetKeyIdAsGuid(contentKeyData.Id));
            }

            EventHandler <BlobTransferProgressChangedEventArgs> handler = (s, e) => OnUploadProgressChanged(path, e);

            blobTransferClient.TransferProgressChanged += handler;

            MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetBlobStorageClientRetryPolicy();

            return(blobTransferClient.UploadBlob(
                       new Uri(locator.Path),
                       path,
                       null,
                       fileEncryption,
                       token,
                       retryPolicy.AsAzureStorageClientRetryPolicy())
                   .ContinueWith(
                       ts =>
            {
                blobTransferClient.TransferProgressChanged -= handler;
                this.PostUploadAction(ts, path, fileEncryption, assetCreationOptions, token);
            }));
        }
Example #11
0
        public override Task <IAssetFile> CreateAsync(string name, CancellationToken cancelation)
        {
            if (_parentAsset == null)
            {
                throw new InvalidOperationException(StringTable.AssetFileCreateParentAssetIsNull);
            }

            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, StringTable.ErrorCreatingAssetFileEmptyFileName));
            }

            cancelation.ThrowIfCancellationRequested();
            IMediaDataServiceContext dataContext = null;
            AssetFileData            assetFile   = null;

            return(Task.Factory.StartNew(() =>
            {
                cancelation.ThrowIfCancellationRequested();
                dataContext = MediaContext.MediaServicesClassFactory.CreateDataServiceContext();

                FileEncryption fileEncryption = null;

                // Set a MIME type based on the extension of the file name
                string mimeType = AssetFileData.GetMimeType(name);
                assetFile = new AssetFileData
                {
                    Name = name,
                    ParentAssetId = _parentAsset.Id,
                    MimeType = mimeType,
                };
                try
                {
                    // Update the files associated with the asset with the encryption related metadata.
                    if (_parentAsset.Options.HasFlag(AssetCreationOptions.StorageEncrypted))
                    {
                        IContentKey storageEncryptionKey = _parentAsset.ContentKeys.Where(c => c.ContentKeyType == ContentKeyType.StorageEncryption).FirstOrDefault();
                        cancelation.ThrowIfCancellationRequested();
                        if (storageEncryptionKey == null)
                        {
                            throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, StringTable.StorageEncryptionContentKeyIsMissing, _parentAsset.Id));
                        }
                        fileEncryption = new FileEncryption(storageEncryptionKey.GetClearKeyValue(), EncryptionUtils.GetKeyIdAsGuid(storageEncryptionKey.Id));
                        AssetBaseCollection.AddEncryptionMetadataToAssetFile(assetFile, fileEncryption);
                    }
                    else if (_parentAsset.Options.HasFlag(AssetCreationOptions.CommonEncryptionProtected))
                    {
                        AssetBaseCollection.SetAssetFileForCommonEncryption(assetFile);
                    }
                    else if (_parentAsset.Options.HasFlag(AssetCreationOptions.EnvelopeEncryptionProtected))
                    {
                        AssetBaseCollection.SetAssetFileForEnvelopeEncryption(assetFile);
                    }
                }
                finally
                {
                    if (fileEncryption != null)
                    {
                        fileEncryption.Dispose();
                    }
                }
                dataContext.AddObject(FileSet, assetFile);
                cancelation.ThrowIfCancellationRequested();
                cancelation.ThrowIfCancellationRequested();
                MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter);
                return retryPolicy.ExecuteAsync <IMediaDataServiceResponse>(() =>
                {
                    cancelation.ThrowIfCancellationRequested();
                    return dataContext.SaveChangesAsync(assetFile);
                }, cancelation).Result;
            }, cancelation)
                   .ContinueWith <IAssetFile>(t =>
            {
                t.ThrowIfFaulted();
                AssetFileData data = (AssetFileData)t.Result.AsyncState;
                return data;
            }, cancelation));
        }
        private void AssetEncryptAction(string outputPath, bool overwriteExistingEncryptedFiles, CancellationToken cancellationToken, ConcurrentDictionary <string, IContentKey> keys, IIngestManifestAsset asset)
        {
            cancellationToken.ThrowIfCancellationRequested();

            List <Task> encryptTasks = new List <Task>();

            AssetCreationOptions assetCreationOptions = asset.Asset.Options;

            if (assetCreationOptions.HasFlag(AssetCreationOptions.StorageEncrypted))
            {
                IContentKey contentKeyData = keys[asset.Id];
                var         fileEncryption = new FileEncryption(contentKeyData.GetClearKeyValue(), EncryptionUtils.GetKeyIdAsGuid(contentKeyData.Id));


                foreach (IngestManifestFileData file in asset.IngestManifestFiles)
                {
                    ulong iv = Convert.ToUInt64(file.InitializationVector, CultureInfo.InvariantCulture);
                    fileEncryption.SetInitializationVectorForFile(file.Name, iv);

                    FileInfo fileInfo = null;
                    fileInfo = TrackedFilesPaths.ContainsKey(file.Id) ? new FileInfo(TrackedFilesPaths[file.Id]) : new FileInfo(file.Name);

                    string destinationPath = Path.Combine(outputPath, fileInfo.Name);
                    if (File.Exists(destinationPath))
                    {
                        if (overwriteExistingEncryptedFiles)
                        {
                            File.Delete(destinationPath);
                        }
                        else
                        {
                            throw new IOException(string.Format(CultureInfo.InvariantCulture, StringTable.BulkIngestFileExists, destinationPath));
                        }
                    }

                    long fileSize     = fileInfo.Length;
                    int  maxBlockSize = GetBlockSize(fileSize);

                    int numThreads = MaxNumberOfEncryptionThreadsForFilePerCore * Environment.ProcessorCount;
                    ConcurrentQueue <Tuple <int, int> > queue = PrepareUploadQueue(maxBlockSize, fileSize);
                    if (queue.Count < numThreads)
                    {
                        numThreads = queue.Count;
                    }


                    File.Create(destinationPath).Dispose();

                    Action action = GetEncryptionAction(cancellationToken, fileEncryption, file, destinationPath, fileInfo, queue, maxBlockSize);
                    for (int i = 0; i < numThreads; i++)
                    {
                        encryptTasks.Add(Task.Factory.StartNew((action), cancellationToken));
                    }
                }
                try
                {
                    Task.WaitAll(encryptTasks.ToArray());
                }
                finally
                {
                    fileEncryption.Dispose();
                }
            }
        }
        /// <summary>
        /// Uploads the stream asynchronously
        /// </summary>
        /// <param name="stream">The stream to upload</param>
        /// <param name="blobTransferClient">The <see cref="BlobTransferClient"/> which is used to upload files.</param>
        /// <param name="locator">An locator <see cref="ILocator"/> which defines permissions associated with the Asset.</param>
        /// <param name="token">A <see cref="CancellationToken"/> to use for canceling upload operation.</param>
        /// <returns>A function delegate that returns the future result to be available through the Task.</returns>
        public Task UploadAsync(Stream stream, BlobTransferClient blobTransferClient, ILocator locator, CancellationToken token)
        {
            if (this.IsFragmented())
            {
                throw new NotSupportedException(StringTable.NotSupportedFragblobUpload);
            }

            if (blobTransferClient == null)
            {
                throw new ArgumentNullException("blobTransferClient");
            }

            if (locator == null)
            {
                throw new ArgumentNullException("locator");
            }

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            IContentKey          contentKeyData       = null;
            FileEncryption       fileEncryption       = null;
            AssetCreationOptions assetCreationOptions = this.Asset.Options;

            if (assetCreationOptions.HasFlag(AssetCreationOptions.StorageEncrypted))
            {
                contentKeyData = this.Asset.ContentKeys.FirstOrDefault(c => c.ContentKeyType == ContentKeyType.StorageEncryption);
                if (contentKeyData == null)
                {
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, StringTable.StorageEncryptionContentKeyIsMissing, this.Asset.Id));
                }

                fileEncryption = new FileEncryption(contentKeyData.GetClearKeyValue(), EncryptionUtils.GetKeyIdAsGuid(contentKeyData.Id));
                ulong iv = Convert.ToUInt64(this.InitializationVector, CultureInfo.InvariantCulture);
                fileEncryption.SetInitializationVectorForFile(this.Name, iv);
            }

            EventHandler <BlobTransferProgressChangedEventArgs> handler = (s, e) => OnUploadProgressChanged(this.Name, e);

            blobTransferClient.TransferProgressChanged += handler;

            MediaRetryPolicy retryPolicy = this.GetMediaContext().MediaServicesClassFactory.GetBlobStorageClientRetryPolicy();

            var streamLength = stream.Length;

            return(blobTransferClient.UploadBlob(
                       new Uri(locator.BaseUri),
                       this.Name,
                       stream,
                       null,
                       fileEncryption,
                       token,
                       retryPolicy.AsAzureStorageClientRetryPolicy(),
                       () => locator.ContentAccessComponent)
                   .ContinueWith(
                       ts =>
            {
                blobTransferClient.TransferProgressChanged -= handler;
                this.PostUploadAction(ts, streamLength, token);
            }));
        }
        private static void SetEncryptionSettings(IIngestManifestAsset ingestManifestAsset, AssetCreationOptions options, IngestManifestFileData data)
        {
            if (options.HasFlag(AssetCreationOptions.StorageEncrypted))
            {
                var contentKeyData = ingestManifestAsset.Asset.ContentKeys.Where(c => c.ContentKeyType == ContentKeyType.StorageEncryption).FirstOrDefault();
                if (contentKeyData == null)
                {
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, StringTable.StorageEncryptionContentKeyIsMissing, ingestManifestAsset.Asset.Id));
                }
                using (var fileEncryption = new FileEncryption(contentKeyData.GetClearKeyValue(), EncryptionUtils.GetKeyIdAsGuid(contentKeyData.Id)))
                {
                    if (!fileEncryption.IsInitializationVectorPresent(data.Name))
                    {
                        fileEncryption.CreateInitializationVectorForFile(data.Name);
                    }
                    ulong iv = fileEncryption.GetInitializationVectorForFile(data.Name);

                    data.IsEncrypted          = true;
                    data.EncryptionKeyId      = fileEncryption.GetKeyIdentifierAsString();
                    data.EncryptionScheme     = FileEncryption.SchemeName;
                    data.EncryptionVersion    = FileEncryption.SchemeVersion;
                    data.InitializationVector = iv.ToString(CultureInfo.InvariantCulture);
                }
            }
            else if (options.HasFlag(AssetCreationOptions.CommonEncryptionProtected))
            {
                data.IsEncrypted       = true;
                data.EncryptionScheme  = CommonEncryption.SchemeName;
                data.EncryptionVersion = CommonEncryption.SchemeVersion;
            }
            else if (options.HasFlag(AssetCreationOptions.EnvelopeEncryptionProtected))
            {
                data.IsEncrypted       = true;
                data.EncryptionScheme  = EnvelopeEncryption.SchemeName;
                data.EncryptionVersion = EnvelopeEncryption.SchemeVersion;
            }
        }