| 270 | } |
| 271 | |
| 272 | func newFromConfig(ld blobserver.Loader, config jsonconfig.Obj) (bs blobserver.Storage, err error) { |
| 273 | sto := &storage{} |
| 274 | agreement := config.RequiredString("I_AGREE") |
| 275 | const wantAgreement = "that encryption support hasn't been peer-reviewed, isn't finished, and its format might change." |
| 276 | if agreement != wantAgreement { |
| 277 | return nil, errors.New("use of the 'encrypt' target without the proper I_AGREE value") |
| 278 | } |
| 279 | |
| 280 | keyFile := config.RequiredString("keyFile") |
| 281 | blobStorage := config.RequiredString("blobs") |
| 282 | metaStorage := config.RequiredString("meta") |
| 283 | metaConf := config.RequiredObject("metaIndex") |
| 284 | if err := config.Validate(); err != nil { |
| 285 | return nil, err |
| 286 | } |
| 287 | |
| 288 | sto.index, err = sorted.NewKeyValueMaybeWipe(metaConf) |
| 289 | if err != nil { |
| 290 | return |
| 291 | } |
| 292 | |
| 293 | sto.blobs, err = ld.GetStorage(blobStorage) |
| 294 | if err != nil { |
| 295 | return |
| 296 | } |
| 297 | sto.meta, err = ld.GetStorage(metaStorage) |
| 298 | if err != nil { |
| 299 | return |
| 300 | } |
| 301 | |
| 302 | keyData, err := readKeyFile(keyFile) |
| 303 | if err != nil { |
| 304 | return nil, fmt.Errorf("error reading key file '%s': %w", keyFile, err) |
| 305 | } |
| 306 | |
| 307 | identity, err := age.ParseX25519Identity(keyData) |
| 308 | if err != nil { |
| 309 | return nil, fmt.Errorf("error parsing x25519 identity: %w", err) |
| 310 | } |
| 311 | sto.identity = identity |
| 312 | |
| 313 | start := time.Now() |
| 314 | log.Printf("Reading encryption metadata...") |
| 315 | sto.smallMeta = &metaBlobHeap{} |
| 316 | if err := sto.readAllMetaBlobs(); err != nil { |
| 317 | return nil, fmt.Errorf("error scanning metadata on start-up: %v", err) |
| 318 | } |
| 319 | log.Printf("Read all encryption metadata in %.3f seconds", time.Since(start).Seconds()) |
| 320 | |
| 321 | return sto, nil |
| 322 | } |
| 323 | |
| 324 | func readKeyFile(keyFile string) (string, error) { |
| 325 | if err := checkKeyFilePermissions(keyFile); err != nil { |