internal static PasswordRecord Load(this IPasswordRecord r, byte[] key)
        {
            var record = new PasswordRecord()
            {
                RecordKey      = key,
                Uid            = r.RecordUid,
                Shared         = r.Shared,
                Owner          = r.Owner,
                ClientModified = r.ClientModifiedTime != 0
                    ? DateTimeOffsetExtensions.FromUnixTimeMilliseconds(r.ClientModifiedTime)
                    : DateTimeOffset.Now,
            };

            var data = r.Data.Base64UrlDecode();

            data = CryptoUtils.DecryptAesV1(data, key);
            using (var ms = new MemoryStream(data))
            {
                var parsedData = (RecordData)DataSerializer.ReadObject(ms);
                record.Title    = parsedData.title;
                record.Login    = parsedData.secret1;
                record.Password = parsedData.secret2;
                record.Link     = parsedData.link;
                record.Notes    = parsedData.notes;
                if (parsedData.custom != null)
                {
                    foreach (var cr in parsedData.custom)
                    {
                        record.Custom.Add(new CustomField
                        {
                            Name  = cr.name,
                            Value = cr.value,
                            Type  = cr.type
                        });
                    }
                }
            }

            if (!string.IsNullOrEmpty(r.Extra))
            {
                var extra = CryptoUtils.DecryptAesV1(r.Extra.Base64UrlDecode(), key);
                using (var ms = new MemoryStream(extra))
                {
                    var parsedExtra = (RecordExtra)ExtraSerializer.ReadObject(ms);
                    if (parsedExtra.files != null && parsedExtra.files.Length > 0)
                    {
                        foreach (var file in parsedExtra.files)
                        {
                            var atta = new AttachmentFile
                            {
                                Id           = file.id,
                                Key          = file.key,
                                Name         = file.name,
                                Title        = file.title ?? "",
                                Type         = file.type ?? "",
                                Size         = file.size ?? 0,
                                LastModified = file.lastModified != null
                                    ? DateTimeOffsetExtensions.FromUnixTimeMilliseconds(file.lastModified.Value)
                                    : DateTimeOffset.Now
                            };
                            if (file.thumbs != null)
                            {
                                atta.Thumbnails = file.thumbs
                                                  .Select(t => new AttachmentFileThumb
                                {
                                    Id   = t.id,
                                    Type = t.type,
                                    Size = t.size ?? 0
                                })
                                                  .ToArray();
                            }

                            record.Attachments.Add(atta);
                        }
                    }

                    if (parsedExtra.fields != null)
                    {
                        foreach (var field in parsedExtra.fields)
                        {
                            var fld = new ExtraField();
                            foreach (var pair in field)
                            {
                                switch (pair.Key)
                                {
                                case "id":
                                    fld.Id = pair.Value.ToString();
                                    break;

                                case "field_type":
                                    fld.FieldType = pair.Value.ToString();
                                    break;

                                case "field_title":
                                    fld.FieldTitle = pair.Value.ToString();
                                    break;

                                default:
                                    fld.Custom[pair.Key] = pair.Value;
                                    break;
                                }
                            }

                            record.ExtraFields.Add(fld);
                        }
                    }
                }
            }

            return(record);
        }
Example #2
0
            /// <summary>
            /// Encrypts and uploads file attachment.
            /// </summary>
            /// <param name="record">Keeper record.</param>
            /// <param name="uploadTask">Upload task</param>
            /// <returns>Awaitable task.</returns>
            /// <seealso cref="IVaultFileAttachment.UploadAttachment"/>
            public async Task UploadAttachment(PasswordRecord record, IAttachmentUploadTask uploadTask)
            {
                var fileStream = uploadTask.Stream;

                if (fileStream == null)
                {
                    throw new KeeperInvalidParameter("Vault::UploadAttachment", "uploadTask", "GetStream()", "null");
                }

                var thumbStream = uploadTask.Thumbnail?.Stream;
                var command     = new RequestUploadCommand
                {
                    FileCount      = 1,
                    ThumbnailCount = thumbStream != null ? 1 : 0
                };

                var rs = await Auth.ExecuteAuthCommand <RequestUploadCommand, RequestUploadResponse>(command);

                if (rs.FileUploads == null || rs.FileUploads.Length < 1)
                {
                    throw new KeeperInvalidParameter("Vault::UploadAttachment", "request_upload", "file_uploads", "empty");
                }

                var fileUpload = rs.FileUploads[0];
                UploadParameters thumbUpload = null;

                if (rs.ThumbnailUploads != null && rs.ThumbnailUploads.Length > 0)
                {
                    thumbUpload = rs.ThumbnailUploads[0];
                }

                var key  = CryptoUtils.GenerateEncryptionKey();
                var atta = new AttachmentFile
                {
                    Id           = fileUpload.FileId,
                    Name         = uploadTask.Name,
                    Title        = uploadTask.Title,
                    Key          = key.Base64UrlEncode(),
                    Type         = uploadTask.MimeType,
                    LastModified = DateTimeOffset.Now,
                };
                var transform = new EncryptAesV1Transform(key);

                using (var cryptoStream = new CryptoStream(fileStream, transform, CryptoStreamMode.Read))
                {
                    await UploadSingleFile(fileUpload, cryptoStream);

                    atta.Size = transform.EncryptedBytes;
                }

                if (thumbUpload != null && thumbStream != null)
                {
                    try
                    {
                        transform = new EncryptAesV1Transform(key);
                        using (var cryptoStream = new CryptoStream(thumbStream, transform, CryptoStreamMode.Read))
                        {
                            await UploadSingleFile(thumbUpload, cryptoStream);
                        }

                        var thumbnail = new AttachmentFileThumb
                        {
                            Id   = thumbUpload.FileId,
                            Type = uploadTask.Thumbnail.MimeType,
                            Size = uploadTask.Thumbnail.Size
                        };
                        var ts = new[] { thumbnail };
                        atta.Thumbnails = atta.Thumbnails == null ? ts : atta.Thumbnails.Concat(ts).ToArray();
                    }
                    catch (Exception e)
                    {
                        Trace.TraceError("Upload Thumbnail: {0}: \"{1}\"", e.GetType().Name, e.Message);
                    }
                }

                record.Attachments.Add(atta);
            }