private void HandlePendingMissingFileKeys(ApiMissingFileKeys missingFileKeys, UserPrivateKey thisUserPrivateKey) { if (missingFileKeys == null || missingFileKeys.Items.Count == 0) { return; } Dictionary <long, UserPublicKey> userPublicKeys = UserMapper.ConvertApiUserIdPublicKeys(missingFileKeys.UserPublicKey); Dictionary <long, PlainFileKey> plainFileKeys = GeneratePlainFileKeyMap(missingFileKeys.FileKeys, thisUserPrivateKey); ApiSetUserFileKeysRequest setUserFileKeysRequest = new ApiSetUserFileKeysRequest { Items = new List <ApiSetUserFileKey>(missingFileKeys.UserPublicKey.Count) }; foreach (ApiUserIdFileId currentMissingFileKey in missingFileKeys.Items) { UserPublicKey currentUsersPublicKey = userPublicKeys[currentMissingFileKey.UserId]; PlainFileKey currentPlainFileKey = plainFileKeys[currentMissingFileKey.FileId]; EncryptedFileKey currentEncryptedFileKey = EncryptFileKey(currentPlainFileKey, currentUsersPublicKey, currentMissingFileKey.FileId); ApiSetUserFileKey newRequestEntry = new ApiSetUserFileKey { FileId = currentMissingFileKey.FileId, UserId = currentMissingFileKey.UserId, FileKey = FileMapper.ToApiFileKey(currentEncryptedFileKey) }; setUserFileKeysRequest.Items.Add(newRequestEntry); } IRestRequest restRequest = _client.Builder.PostMissingFileKeys(setUserFileKeysRequest); _client.Executor.DoSyncApiCall <VoidResponse>(restRequest, RequestType.PostMissingFileKeys); }
/// <summary> /// Decrypts a file key. /// </summary> /// <param name="encFileKey">The file key to decrypt.</param> /// <param name="userPrivateKey">The private key which should be used for the decryption.</param> /// <param name="password">The password which secures the private key.</param> /// <returns>The decrypted file key.</returns> /// <exception cref="Dracoon.Crypto.Sdk.InvalidFileKeyException">If the provided encrypted file key is invalid.</exception> /// <exception cref="Dracoon.Crypto.Sdk.InvalidKeyPairException">If the provided private key is invalid.</exception> /// <exception cref="Dracoon.Crypto.Sdk.InvalidPasswordException">If the provided private key password is invalid</exception> /// <exception cref="Dracoon.Crypto.Sdk.CryptoException">If an unexpected error in the decryption occured.</exception> public static PlainFileKey DecryptFileKey(EncryptedFileKey encFileKey, UserPrivateKey userPrivateKey, string password) { ValidateEncryptedFileKey(encFileKey); ValidateUserPrivateKey(userPrivateKey); ValidatePassword(password); AsymmetricKeyParameter privateKey = DecryptPrivateKey(userPrivateKey.PrivateKey, password); byte[] dFileKey; try { OaepEncoding engine = new OaepEncoding(new RsaEngine(), new Sha256Digest(), new Sha1Digest(), null); engine.Init(false, privateKey); byte[] eFileKey = Convert.FromBase64String(encFileKey.Key); dFileKey = engine.ProcessBlock(eFileKey, 0, eFileKey.Length); } catch (InvalidCipherTextException e) { throw new CryptoException("Could not decrypt file key. Decryption failed.", e); } PlainFileKey plainFileKey = new PlainFileKey() { Key = Convert.ToBase64String(dFileKey), Iv = encFileKey.Iv, Tag = encFileKey.Tag, Version = encFileKey.Version }; return(plainFileKey); }
private PlainFileKey TestDecryptFileKey(byte[] encryptedFileKeyResource, byte[] userPrivateKeyResource, string password) { EncryptedFileKey efk = TestUtilities.ReadTestResource <EncryptedFileKey>(encryptedFileKeyResource); UserPrivateKey upk = TestUtilities.ReadTestResource <UserPrivateKey>(userPrivateKeyResource); return(Crypto.DecryptFileKey(efk, upk, password)); }
/// <summary> /// Encrypts a file key. /// </summary> /// <param name="plainFileKey">The file key to encrypt.</param> /// <param name="userPublicKey">The public key which should be used for the encryption.</param> /// <returns>The encrypted file key.</returns> /// <exception cref="Dracoon.Crypto.Sdk.InvalidFileKeyException">If the provided file key is invalid.</exception> /// <exception cref="Dracoon.Crypto.Sdk.InvalidKeyPairException">If the provided public key is invalid.</exception> /// <exception cref="Dracoon.Crypto.Sdk.CryptoException">If an unexpected error occured.</exception> public static EncryptedFileKey EncryptFileKey(PlainFileKey plainFileKey, UserPublicKey userPublicKey) { ValidatePlainFileKey(plainFileKey); ValidateUserPublicKey(userPublicKey); AsymmetricKeyParameter pubKey = ConvertPublicKey(userPublicKey.PublicKey); byte[] eFileKey; try { OaepEncoding engine = new OaepEncoding(new RsaEngine(), new Sha256Digest(), new Sha1Digest(), null); engine.Init(true, pubKey); byte[] pFileKey = Convert.FromBase64String(plainFileKey.Key); eFileKey = engine.ProcessBlock(pFileKey, 0, pFileKey.Length); } catch (Exception e) { throw new CryptoException("Could not encrypt file key. Encryption failed.", e); } EncryptedFileKey encFileKey = new EncryptedFileKey() { Key = Convert.ToBase64String(eFileKey), Iv = plainFileKey.Iv, Tag = plainFileKey.Tag, Version = plainFileKey.Version }; return(encFileKey); }
private PlainFileKey DecryptFileKey(EncryptedFileKey encryptedFileKey) { try { return(Crypto.Sdk.Crypto.DecryptFileKey(encryptedFileKey, _userPrivateKey, Client.EncryptionPassword)); } catch (CryptoException ce) { string message = "Decryption of file key for encrypted download " + ActionId + " failed!"; DracoonClient.Log.Debug(Logtag, message); throw new DracoonCryptoException(CryptoErrorMapper.ParseCause(ce), ce); } }
protected override void StartDownload() { NotifyStarted(ActionId); IRestRequest downloadTokenRequest = Client.Builder.PostFileDownload(AssociatedNode.Id); ApiDownloadToken token = Client.Executor.DoSyncApiCall <ApiDownloadToken>(downloadTokenRequest, RequestType.PostDownloadToken); EncryptedFileKey encryptedFileKey = Client.NodesImpl.GetEncryptedFileKey(AssociatedNode.Id); EncryptedDownload(new Uri(token.DownloadUrl), DecryptFileKey(encryptedFileKey)); NotifyFinished(ActionId); }
internal PlainFileKey DecryptFileKey(EncryptedFileKey encryptedFileKey, UserPrivateKey userPrivateKey, long?nodeId = null) { try { return(Crypto.Sdk.Crypto.DecryptFileKey(encryptedFileKey, userPrivateKey, _client.EncryptionPassword)); } catch (CryptoException ce) { string message = "Decryption file key for node " + (nodeId.HasValue ? nodeId.Value.ToString() : "NULL") + " failed with " + ce.Message; DracoonClient.Log.Debug(Logtag, message); throw new DracoonCryptoException(CryptoErrorMapper.ParseCause(ce), ce); } }
internal static EncryptedFileKey FromApiFileKey(ApiFileKey apiEncryptedFileKey) { EncryptedFileKey encryptedFileKey = new EncryptedFileKey { Key = apiEncryptedFileKey.Key, Iv = apiEncryptedFileKey.Iv, Tag = apiEncryptedFileKey.Tag, Version = apiEncryptedFileKey.Version }; return(encryptedFileKey); }
internal static ApiFileKey ToApiFileKey(EncryptedFileKey encryptedFileKey) { ApiFileKey apiEncryptedFileKey = new ApiFileKey { Key = encryptedFileKey.Key, Iv = encryptedFileKey.Iv, Tag = encryptedFileKey.Tag, Version = encryptedFileKey.Version }; return(apiEncryptedFileKey); }
/// <summary> /// Checks the encrypted file key for file encryption. /// </summary> /// <param name="encFileKey">The encrypted file key to check.</param> /// /// <exception cref="Dracoon.Crypto.Sdk.InvalidFileKeyException"/> private static void ValidateEncryptedFileKey(EncryptedFileKey encFileKey) { if (encFileKey == null) { throw new InvalidFileKeyException("File key cannot be null."); } if (encFileKey.Version == null || !encFileKey.Version.Equals(CryptoConstants.defaultVersion)) { throw new InvalidFileKeyException("Unknown file key version."); } }
private Dictionary <long, PlainFileKey> GeneratePlainFileKeyMap(List <ApiFileIdFileKey> fileIdFileKeys, UserPrivateKey thisUserPrivateKey) { Dictionary <long, PlainFileKey> plainFileKeys = new Dictionary <long, PlainFileKey>(fileIdFileKeys.Count); foreach (ApiFileIdFileKey currentEncryptedFileKey in fileIdFileKeys) { EncryptedFileKey encryptedFileKey = FileMapper.FromApiFileKey(currentEncryptedFileKey.FileKeyContainer); PlainFileKey decryptedFileKey = DecryptFileKey(encryptedFileKey, thisUserPrivateKey, currentEncryptedFileKey.FileId); plainFileKeys.Add(currentEncryptedFileKey.FileId, decryptedFileKey); } return(plainFileKeys); }
public void TestEncryptFileKey_Success() { EncryptedFileKey efk = TestUtilities.ReadTestResource <EncryptedFileKey>(TestResources.enc_file_key); EncryptedFileKey testEfk = TestEncryptFileKey(TestResources.plain_file_key, TestResources.public_key); PlainFileKey pfk = TestUtilities.ReadTestResource <PlainFileKey>(TestResources.plain_file_key); PlainFileKey testPfk = Crypto.DecryptFileKey(testEfk, TestUtilities.ReadTestResource <UserPrivateKey>(TestResources.private_key), "Pass1234!"); Assert.AreEqual(pfk.Key, testPfk.Key, "File key is incorrect!"); Assert.AreEqual(efk.Iv, testEfk.Iv, "Initialization vector is incorrect!"); Assert.AreEqual(efk.Tag, testEfk.Tag, "Tag is incorrect!"); Assert.AreEqual(efk.Version, testEfk.Version, "Version is incorrect!"); }
static void Main(String[] args) { // --- INITIALIZATION --- // Generate key pair UserKeyPair userKeyPair = Crypto.GenerateUserKeyPair(USER_PASSWORD); // Check key pair if (!Crypto.CheckUserKeyPair(userKeyPair, USER_PASSWORD)) { Trace.WriteLine("Invalid user password!"); return; } byte[] plainData = Encoding.UTF8.GetBytes(DATA); Trace.WriteLine("Plain Data:"); Trace.WriteLine(Encoding.UTF8.GetString(plainData)); Trace.WriteLine("Plain Data: (BASE64)"); Trace.WriteLine(Convert.ToBase64String(plainData)); // --- ENCRYPTION --- // Generate plain file key PlainFileKey fileKey = Crypto.GenerateFileKey(); // Encrypt blocks byte[] encData = EncryptData(fileKey, plainData); // Encrypt file key EncryptedFileKey encFileKey = Crypto.EncryptFileKey(fileKey, userKeyPair.UserPublicKey); Trace.WriteLine("Encrypted Data: (Base64)"); Trace.WriteLine(Convert.ToBase64String(encData)); // --- DECRYPTION --- // Decrypt file key PlainFileKey decFileKey = Crypto.DecryptFileKey(encFileKey, userKeyPair.UserPrivateKey, USER_PASSWORD); // Decrypt blocks byte[] decData = DecryptData(decFileKey, encData); Trace.WriteLine("Decrypted Data:"); Trace.WriteLine(Encoding.UTF8.GetString(decData)); Trace.WriteLine("Decrypted Data: (BASE64)"); Trace.WriteLine(Convert.ToBase64String(plainData)); }
public void FromApiFileKey() { // ARRANGE EncryptedFileKey expected = FactoryFile.EncryptedFileKey; ApiFileKey param = new ApiFileKey { Iv = expected.Iv, Key = expected.Key, Tag = expected.Tag, Version = expected.Version }; // ACT EncryptedFileKey actual = FileMapper.FromApiFileKey(param); // ASSERT Assert.Equal(expected, actual, new EncryptedFileKeyComparer()); }
protected override Node StartUpload() { NotifyStarted(ActionId); ApiCreateFileUpload apiFileUploadRequest = FileMapper.ToApiCreateFileUpload(FileUploadRequest); try { apiFileUploadRequest.UseS3 = CheckUseS3(); } catch (DracoonApiException apiException) { DracoonClient.Log.Warn(LogTag, "S3 direct upload is not possible.", apiException); } IRestRequest uploadTokenRequest = Client.Builder.PostCreateFileUpload(apiFileUploadRequest); UploadToken = Client.Executor.DoSyncApiCall <ApiUploadToken>(uploadTokenRequest, RequestType.PostUploadToken); Node publicResultNode; PlainFileKey plainFileKey = CreateFileKey(); ApiCompleteFileUpload apiCompleteFileUpload = FileMapper.ToApiCompleteFileUpload(FileUploadRequest); if (apiFileUploadRequest.UseS3.HasValue && apiFileUploadRequest.UseS3.Value) { List <ApiS3FileUploadPart> s3Parts = EncryptedS3Upload(ref plainFileKey); EncryptedFileKey encryptedFileKey = EncryptFileKey(plainFileKey); apiCompleteFileUpload.FileKey = FileMapper.ToApiFileKey(encryptedFileKey); apiCompleteFileUpload.Parts = s3Parts; IRestRequest completeFileUploadRequest = Client.Builder.PutCompleteS3FileUpload(UploadToken.UploadId, apiCompleteFileUpload); Client.Executor.DoSyncApiCall <VoidResponse>(completeFileUploadRequest, RequestType.PutCompleteS3Upload); publicResultNode = NodeMapper.FromApiNode(S3Finished()); } else { EncryptedUpload(ref plainFileKey); EncryptedFileKey encryptedFileKey = EncryptFileKey(plainFileKey); apiCompleteFileUpload.FileKey = FileMapper.ToApiFileKey(encryptedFileKey); IRestRequest completeFileUploadRequest = Client.Builder.PutCompleteFileUpload(new Uri(UploadToken.UploadUrl).PathAndQuery, apiCompleteFileUpload); ApiNode resultNode = Client.Executor.DoSyncApiCall <ApiNode>(completeFileUploadRequest, RequestType.PutCompleteUpload); publicResultNode = NodeMapper.FromApiNode(resultNode); } NotifyFinished(ActionId, publicResultNode); return(publicResultNode); }
public DownloadShare CreateDownloadShare(CreateDownloadShareRequest request) { _client.Executor.CheckApiServerVersion(); #region Parameter Validation request.MustNotNull(nameof(request)); Node targetNode = _client.NodesImpl.GetNode(request.NodeId); // Node id is still checked in previous called getNode() // To save much effort throw this restriction instantly and not let the rest api throw this error if (targetNode.IsEncrypted.GetValueOrDefault(false) && targetNode.Type != NodeType.File) { throw new DracoonApiException(DracoonApiCode.VALIDATION_DL_SHARE_CANNOT_CREATE_ON_ENCRYPTED_ROOM_FOLDER); } request.Name.MustNotNullOrEmptyOrWhitespace(nameof(request.Name), true); request.MaxAllowedDownloads.NullableMustPositive(nameof(request.MaxAllowedDownloads)); if (targetNode.IsEncrypted.GetValueOrDefault(false) && string.IsNullOrWhiteSpace(request.EncryptionPassword) && !string.IsNullOrWhiteSpace(request.AccessPassword)) { throw new ArgumentException("Download share of a encrypted node must have a encryption password and no access password."); } if (!targetNode.IsEncrypted.GetValueOrDefault(false) && string.IsNullOrWhiteSpace(request.AccessPassword) && !string.IsNullOrWhiteSpace(request.EncryptionPassword)) { throw new ArgumentException("Download share of a not encrypted node must have a access password and no encryption password."); } if (targetNode.IsEncrypted.GetValueOrDefault(false) && string.IsNullOrWhiteSpace(request.EncryptionPassword)) { throw new ArgumentException("Download share of a encrypted node must have a encryption password."); } if (!targetNode.IsEncrypted.GetValueOrDefault(false)) { request.AccessPassword?.MustNotNullOrEmptyOrWhitespace(nameof(request.AccessPassword)); } if (request.EmailRecipients != null) { request.EmailRecipients.EnumerableMustNotNullOrEmpty(nameof(request.EmailRecipients)); request.EmailRecipients.ForEach(current => current.MustNotNullOrEmptyOrWhitespace(nameof(request.EmailRecipients) + " element")); request.EmailBody.MustNotNullOrEmptyOrWhitespace(nameof(request.EmailBody)); request.EmailSubject.MustNotNullOrEmptyOrWhitespace(nameof(request.EmailSubject)); } if (request.SmsRecipients != null) { request.SmsRecipients.EnumerableMustNotNullOrEmpty(nameof(request.SmsRecipients)); request.SmsRecipients.ForEach(current => current.MustNotNullOrEmptyOrWhitespace(nameof(request.SmsRecipients) + " element")); if (string.IsNullOrEmpty(request.AccessPassword)) { throw new ArgumentException("If a SMS should be sent, a access password must be set."); } } #endregion ApiCreateDownloadShareRequest apiRequest = ShareMapper.ToUnencryptedApiCreateDownloadShareRequest(request); if (targetNode.IsEncrypted.GetValueOrDefault(false)) { UserKeyPair creatorKeyPair = _client.AccountImpl.GetAndCheckUserKeyPair(); EncryptedFileKey creatorEncryptedFileKey = _client.NodesImpl.GetEncryptedFileKey(request.NodeId); PlainFileKey plainFileKey = _client.NodesImpl.DecryptFileKey(creatorEncryptedFileKey, creatorKeyPair.UserPrivateKey, request.NodeId); UserKeyPair newGeneratedKeyPair = _client.AccountImpl.GenerateNewUserKeyPair(request.EncryptionPassword); EncryptedFileKey newEncryptedFileKey = _client.NodesImpl.EncryptFileKey(plainFileKey, newGeneratedKeyPair.UserPublicKey, request.NodeId); apiRequest.KeyPair = UserMapper.ToApiUserKeyPair(newGeneratedKeyPair); apiRequest.FileKey = FileMapper.ToApiFileKey(newEncryptedFileKey); } IRestRequest restRequest = _client.Builder.PostCreateDownloadShare(apiRequest); ApiDownloadShare resultShare = _client.Executor.DoSyncApiCall <ApiDownloadShare>(restRequest, DracoonRequestExecutor.RequestType.PostCreateDownloadShare); return(ShareMapper.FromApiDownloadShare(resultShare)); }