1package keysutil 2 3import ( 4 "bytes" 5 "context" 6 "crypto" 7 "crypto/aes" 8 "crypto/cipher" 9 "crypto/ecdsa" 10 "crypto/elliptic" 11 "crypto/hmac" 12 "crypto/rand" 13 "crypto/rsa" 14 "crypto/sha256" 15 "crypto/x509" 16 "encoding/asn1" 17 "encoding/base64" 18 "encoding/json" 19 "encoding/pem" 20 "errors" 21 "fmt" 22 "io" 23 "math/big" 24 "path" 25 "strconv" 26 "strings" 27 "sync" 28 "sync/atomic" 29 "time" 30 31 "golang.org/x/crypto/chacha20poly1305" 32 "golang.org/x/crypto/ed25519" 33 "golang.org/x/crypto/hkdf" 34 35 "github.com/hashicorp/errwrap" 36 uuid "github.com/hashicorp/go-uuid" 37 "github.com/hashicorp/vault/sdk/helper/errutil" 38 "github.com/hashicorp/vault/sdk/helper/jsonutil" 39 "github.com/hashicorp/vault/sdk/helper/kdf" 40 "github.com/hashicorp/vault/sdk/logical" 41) 42 43// Careful with iota; don't put anything before it in this const block because 44// we need the default of zero to be the old-style KDF 45const ( 46 Kdf_hmac_sha256_counter = iota // built-in helper 47 Kdf_hkdf_sha256 // golang.org/x/crypto/hkdf 48) 49 50// Or this one...we need the default of zero to be the original AES256-GCM96 51const ( 52 KeyType_AES256_GCM96 = iota 53 KeyType_ECDSA_P256 54 KeyType_ED25519 55 KeyType_RSA2048 56 KeyType_RSA4096 57 KeyType_ChaCha20_Poly1305 58) 59 60const ( 61 // ErrTooOld is returned whtn the ciphertext or signatures's key version is 62 // too old. 63 ErrTooOld = "ciphertext or signature version is disallowed by policy (too old)" 64 65 // DefaultVersionTemplate is used when no version template is provided. 66 DefaultVersionTemplate = "vault:v{{version}}:" 67) 68 69type RestoreInfo struct { 70 Time time.Time `json:"time"` 71 Version int `json:"version"` 72} 73 74type BackupInfo struct { 75 Time time.Time `json:"time"` 76 Version int `json:"version"` 77} 78 79type SigningResult struct { 80 Signature string 81 PublicKey []byte 82} 83 84type ecdsaSignature struct { 85 R, S *big.Int 86} 87 88type KeyType int 89 90func (kt KeyType) EncryptionSupported() bool { 91 switch kt { 92 case KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_RSA2048, KeyType_RSA4096: 93 return true 94 } 95 return false 96} 97 98func (kt KeyType) DecryptionSupported() bool { 99 switch kt { 100 case KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_RSA2048, KeyType_RSA4096: 101 return true 102 } 103 return false 104} 105 106func (kt KeyType) SigningSupported() bool { 107 switch kt { 108 case KeyType_ECDSA_P256, KeyType_ED25519, KeyType_RSA2048, KeyType_RSA4096: 109 return true 110 } 111 return false 112} 113 114func (kt KeyType) HashSignatureInput() bool { 115 switch kt { 116 case KeyType_ECDSA_P256, KeyType_RSA2048, KeyType_RSA4096: 117 return true 118 } 119 return false 120} 121 122func (kt KeyType) DerivationSupported() bool { 123 switch kt { 124 case KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_ED25519: 125 return true 126 } 127 return false 128} 129 130func (kt KeyType) String() string { 131 switch kt { 132 case KeyType_AES256_GCM96: 133 return "aes256-gcm96" 134 case KeyType_ChaCha20_Poly1305: 135 return "chacha20-poly1305" 136 case KeyType_ECDSA_P256: 137 return "ecdsa-p256" 138 case KeyType_ED25519: 139 return "ed25519" 140 case KeyType_RSA2048: 141 return "rsa-2048" 142 case KeyType_RSA4096: 143 return "rsa-4096" 144 } 145 146 return "[unknown]" 147} 148 149type KeyData struct { 150 Policy *Policy `json:"policy"` 151 ArchivedKeys *archivedKeys `json:"archived_keys"` 152} 153 154// KeyEntry stores the key and metadata 155type KeyEntry struct { 156 // AES or some other kind that is a pure byte slice like ED25519 157 Key []byte `json:"key"` 158 159 // Key used for HMAC functions 160 HMACKey []byte `json:"hmac_key"` 161 162 // Time of creation 163 CreationTime time.Time `json:"time"` 164 165 EC_X *big.Int `json:"ec_x"` 166 EC_Y *big.Int `json:"ec_y"` 167 EC_D *big.Int `json:"ec_d"` 168 169 RSAKey *rsa.PrivateKey `json:"rsa_key"` 170 171 // The public key in an appropriate format for the type of key 172 FormattedPublicKey string `json:"public_key"` 173 174 // If convergent is enabled, the version (falling back to what's in the 175 // policy) 176 ConvergentVersion int `json:"convergent_version"` 177 178 // This is deprecated (but still filled) in favor of the value above which 179 // is more precise 180 DeprecatedCreationTime int64 `json:"creation_time"` 181} 182 183// deprecatedKeyEntryMap is used to allow JSON marshal/unmarshal 184type deprecatedKeyEntryMap map[int]KeyEntry 185 186// MarshalJSON implements JSON marshaling 187func (kem deprecatedKeyEntryMap) MarshalJSON() ([]byte, error) { 188 intermediate := map[string]KeyEntry{} 189 for k, v := range kem { 190 intermediate[strconv.Itoa(k)] = v 191 } 192 return json.Marshal(&intermediate) 193} 194 195// MarshalJSON implements JSON unmarshalling 196func (kem deprecatedKeyEntryMap) UnmarshalJSON(data []byte) error { 197 intermediate := map[string]KeyEntry{} 198 if err := jsonutil.DecodeJSON(data, &intermediate); err != nil { 199 return err 200 } 201 for k, v := range intermediate { 202 keyval, err := strconv.Atoi(k) 203 if err != nil { 204 return err 205 } 206 kem[keyval] = v 207 } 208 209 return nil 210} 211 212// keyEntryMap is used to allow JSON marshal/unmarshal 213type keyEntryMap map[string]KeyEntry 214 215// PolicyConfig is used to create a new policy 216type PolicyConfig struct { 217 // The name of the policy 218 Name string `json:"name"` 219 220 // The type of key 221 Type KeyType 222 223 // Derived keys MUST provide a context and the master underlying key is 224 // never used. 225 Derived bool 226 KDF int 227 ConvergentEncryption bool 228 229 // Whether the key is exportable 230 Exportable bool 231 232 // Whether the key is allowed to be deleted 233 DeletionAllowed bool 234 235 // AllowPlaintextBackup allows taking backup of the policy in plaintext 236 AllowPlaintextBackup bool 237 238 // VersionTemplate is used to prefix the ciphertext with information about 239 // the key version. It must inclide {{version}} and a delimiter between the 240 // version prefix and the ciphertext. 241 VersionTemplate string 242 243 // StoragePrefix is used to add a prefix when storing and retrieving the 244 // policy object. 245 StoragePrefix string 246} 247 248// NewPolicy takes a policy config and returns a Policy with those settings. 249func NewPolicy(config PolicyConfig) *Policy { 250 return &Policy{ 251 l: new(sync.RWMutex), 252 Name: config.Name, 253 Type: config.Type, 254 Derived: config.Derived, 255 KDF: config.KDF, 256 ConvergentEncryption: config.ConvergentEncryption, 257 ConvergentVersion: -1, 258 Exportable: config.Exportable, 259 DeletionAllowed: config.DeletionAllowed, 260 AllowPlaintextBackup: config.AllowPlaintextBackup, 261 VersionTemplate: config.VersionTemplate, 262 StoragePrefix: config.StoragePrefix, 263 } 264} 265 266// LoadPolicy will load a policy from the provided storage path and set the 267// necessary un-exported variables. It is particularly useful when accessing a 268// policy without the lock manager. 269func LoadPolicy(ctx context.Context, s logical.Storage, path string) (*Policy, error) { 270 raw, err := s.Get(ctx, path) 271 if err != nil { 272 return nil, err 273 } 274 if raw == nil { 275 return nil, nil 276 } 277 278 var policy Policy 279 err = jsonutil.DecodeJSON(raw.Value, &policy) 280 if err != nil { 281 return nil, err 282 } 283 284 policy.l = new(sync.RWMutex) 285 286 return &policy, nil 287} 288 289// Policy is the struct used to store metadata 290type Policy struct { 291 // This is a pointer on purpose: if we are running with cache disabled we 292 // need to actually swap in the lock manager's lock for this policy with 293 // the local lock. 294 l *sync.RWMutex 295 // writeLocked allows us to implement Lock() and Unlock() 296 writeLocked bool 297 // Stores whether it's been deleted. This acts as a guard for operations 298 // that may write data, e.g. if one request rotates and that request is 299 // served after a delete. 300 deleted uint32 301 302 Name string `json:"name"` 303 Key []byte `json:"key,omitempty"` //DEPRECATED 304 Keys keyEntryMap `json:"keys"` 305 306 // Derived keys MUST provide a context and the master underlying key is 307 // never used. If convergent encryption is true, the context will be used 308 // as the nonce as well. 309 Derived bool `json:"derived"` 310 KDF int `json:"kdf"` 311 ConvergentEncryption bool `json:"convergent_encryption"` 312 313 // Whether the key is exportable 314 Exportable bool `json:"exportable"` 315 316 // The minimum version of the key allowed to be used for decryption 317 MinDecryptionVersion int `json:"min_decryption_version"` 318 319 // The minimum version of the key allowed to be used for encryption 320 MinEncryptionVersion int `json:"min_encryption_version"` 321 322 // The latest key version in this policy 323 LatestVersion int `json:"latest_version"` 324 325 // The latest key version in the archive. We never delete these, so this is 326 // a max. 327 ArchiveVersion int `json:"archive_version"` 328 329 // ArchiveMinVersion is the minimum version of the key in the archive. 330 ArchiveMinVersion int `json:"archive_min_version"` 331 332 // MinAvailableVersion is the minimum version of the key present. All key 333 // versions before this would have been deleted. 334 MinAvailableVersion int `json:"min_available_version"` 335 336 // Whether the key is allowed to be deleted 337 DeletionAllowed bool `json:"deletion_allowed"` 338 339 // The version of the convergent nonce to use 340 ConvergentVersion int `json:"convergent_version"` 341 342 // The type of key 343 Type KeyType `json:"type"` 344 345 // BackupInfo indicates the information about the backup action taken on 346 // this policy 347 BackupInfo *BackupInfo `json:"backup_info"` 348 349 // RestoreInfo indicates the information about the restore action taken on 350 // this policy 351 RestoreInfo *RestoreInfo `json:"restore_info"` 352 353 // AllowPlaintextBackup allows taking backup of the policy in plaintext 354 AllowPlaintextBackup bool `json:"allow_plaintext_backup"` 355 356 // VersionTemplate is used to prefix the ciphertext with information about 357 // the key version. It must inclide {{version}} and a delimiter between the 358 // version prefix and the ciphertext. 359 VersionTemplate string `json:"version_template"` 360 361 // StoragePrefix is used to add a prefix when storing and retrieving the 362 // policy object. 363 StoragePrefix string `json:"storage_prefix"` 364 365 // versionPrefixCache stores caches of version prefix strings and the split 366 // version template. 367 versionPrefixCache sync.Map 368} 369 370func (p *Policy) Lock(exclusive bool) { 371 if exclusive { 372 p.l.Lock() 373 p.writeLocked = true 374 } else { 375 p.l.RLock() 376 } 377} 378 379func (p *Policy) Unlock() { 380 if p.writeLocked { 381 p.writeLocked = false 382 p.l.Unlock() 383 } else { 384 p.l.RUnlock() 385 } 386} 387 388// ArchivedKeys stores old keys. This is used to keep the key loading time sane 389// when there are huge numbers of rotations. 390type archivedKeys struct { 391 Keys []KeyEntry `json:"keys"` 392} 393 394func (p *Policy) LoadArchive(ctx context.Context, storage logical.Storage) (*archivedKeys, error) { 395 archive := &archivedKeys{} 396 397 raw, err := storage.Get(ctx, path.Join(p.StoragePrefix, "archive", p.Name)) 398 if err != nil { 399 return nil, err 400 } 401 if raw == nil { 402 archive.Keys = make([]KeyEntry, 0) 403 return archive, nil 404 } 405 406 if err := jsonutil.DecodeJSON(raw.Value, archive); err != nil { 407 return nil, err 408 } 409 410 return archive, nil 411} 412 413func (p *Policy) storeArchive(ctx context.Context, storage logical.Storage, archive *archivedKeys) error { 414 // Encode the policy 415 buf, err := json.Marshal(archive) 416 if err != nil { 417 return err 418 } 419 420 // Write the policy into storage 421 err = storage.Put(ctx, &logical.StorageEntry{ 422 Key: path.Join(p.StoragePrefix, "archive", p.Name), 423 Value: buf, 424 }) 425 if err != nil { 426 return err 427 } 428 429 return nil 430} 431 432// handleArchiving manages the movement of keys to and from the policy archive. 433// This should *ONLY* be called from Persist() since it assumes that the policy 434// will be persisted afterwards. 435func (p *Policy) handleArchiving(ctx context.Context, storage logical.Storage) error { 436 // We need to move keys that are no longer accessible to archivedKeys, and keys 437 // that now need to be accessible back here. 438 // 439 // For safety, because there isn't really a good reason to, we never delete 440 // keys from the archive even when we move them back. 441 442 // Check if we have the latest minimum version in the current set of keys 443 _, keysContainsMinimum := p.Keys[strconv.Itoa(p.MinDecryptionVersion)] 444 445 // Sanity checks 446 switch { 447 case p.MinDecryptionVersion < 1: 448 return fmt.Errorf("minimum decryption version of %d is less than 1", p.MinDecryptionVersion) 449 case p.LatestVersion < 1: 450 return fmt.Errorf("latest version of %d is less than 1", p.LatestVersion) 451 case !keysContainsMinimum && p.ArchiveVersion != p.LatestVersion: 452 return fmt.Errorf("need to move keys from archive but archive version not up-to-date") 453 case p.ArchiveVersion > p.LatestVersion: 454 return fmt.Errorf("archive version of %d is greater than the latest version %d", 455 p.ArchiveVersion, p.LatestVersion) 456 case p.MinEncryptionVersion > 0 && p.MinEncryptionVersion < p.MinDecryptionVersion: 457 return fmt.Errorf("minimum decryption version of %d is greater than minimum encryption version %d", 458 p.MinDecryptionVersion, p.MinEncryptionVersion) 459 case p.MinDecryptionVersion > p.LatestVersion: 460 return fmt.Errorf("minimum decryption version of %d is greater than the latest version %d", 461 p.MinDecryptionVersion, p.LatestVersion) 462 } 463 464 archive, err := p.LoadArchive(ctx, storage) 465 if err != nil { 466 return err 467 } 468 469 if !keysContainsMinimum { 470 // Need to move keys *from* archive 471 for i := p.MinDecryptionVersion; i <= p.LatestVersion; i++ { 472 p.Keys[strconv.Itoa(i)] = archive.Keys[i-p.MinAvailableVersion] 473 } 474 475 return nil 476 } 477 478 // Need to move keys *to* archive 479 480 // We need a size that is equivalent to the latest version (number of keys) 481 // but adding one since slice numbering starts at 0 and we're indexing by 482 // key version 483 if len(archive.Keys)+p.MinAvailableVersion < p.LatestVersion+1 { 484 // Increase the size of the archive slice 485 newKeys := make([]KeyEntry, p.LatestVersion-p.MinAvailableVersion+1) 486 copy(newKeys, archive.Keys) 487 archive.Keys = newKeys 488 } 489 490 // We are storing all keys in the archive, so we ensure that it is up to 491 // date up to p.LatestVersion 492 for i := p.ArchiveVersion + 1; i <= p.LatestVersion; i++ { 493 archive.Keys[i-p.MinAvailableVersion] = p.Keys[strconv.Itoa(i)] 494 p.ArchiveVersion = i 495 } 496 497 // Trim the keys if required 498 if p.ArchiveMinVersion < p.MinAvailableVersion { 499 archive.Keys = archive.Keys[p.MinAvailableVersion-p.ArchiveMinVersion:] 500 p.ArchiveMinVersion = p.MinAvailableVersion 501 } 502 503 err = p.storeArchive(ctx, storage, archive) 504 if err != nil { 505 return err 506 } 507 508 // Perform deletion afterwards so that if there is an error saving we 509 // haven't messed with the current policy 510 for i := p.LatestVersion - len(p.Keys) + 1; i < p.MinDecryptionVersion; i++ { 511 delete(p.Keys, strconv.Itoa(i)) 512 } 513 514 return nil 515} 516 517func (p *Policy) Persist(ctx context.Context, storage logical.Storage) (retErr error) { 518 if atomic.LoadUint32(&p.deleted) == 1 { 519 return errors.New("key has been deleted, not persisting") 520 } 521 522 // Other functions will take care of restoring other values; this is just 523 // responsible for archiving and keys since the archive function can modify 524 // keys. At the moment one of the other functions calling persist will also 525 // roll back keys, but better safe than sorry and this doesn't happen 526 // enough to worry about the speed tradeoff. 527 priorArchiveVersion := p.ArchiveVersion 528 var priorKeys keyEntryMap 529 530 if p.Keys != nil { 531 priorKeys = keyEntryMap{} 532 for k, v := range p.Keys { 533 priorKeys[k] = v 534 } 535 } 536 537 defer func() { 538 if retErr != nil { 539 p.ArchiveVersion = priorArchiveVersion 540 p.Keys = priorKeys 541 } 542 }() 543 544 err := p.handleArchiving(ctx, storage) 545 if err != nil { 546 return err 547 } 548 549 // Encode the policy 550 buf, err := p.Serialize() 551 if err != nil { 552 return err 553 } 554 555 // Write the policy into storage 556 err = storage.Put(ctx, &logical.StorageEntry{ 557 Key: path.Join(p.StoragePrefix, "policy", p.Name), 558 Value: buf, 559 }) 560 if err != nil { 561 return err 562 } 563 564 return nil 565} 566 567func (p *Policy) Serialize() ([]byte, error) { 568 return json.Marshal(p) 569} 570 571func (p *Policy) NeedsUpgrade() bool { 572 // Ensure we've moved from Key -> Keys 573 if p.Key != nil && len(p.Key) > 0 { 574 return true 575 } 576 577 // With archiving, past assumptions about the length of the keys map are no 578 // longer valid 579 if p.LatestVersion == 0 && len(p.Keys) != 0 { 580 return true 581 } 582 583 // We disallow setting the version to 0, since they start at 1 since moving 584 // to rotate-able keys, so update if it's set to 0 585 if p.MinDecryptionVersion == 0 { 586 return true 587 } 588 589 // On first load after an upgrade, copy keys to the archive 590 if p.ArchiveVersion == 0 { 591 return true 592 } 593 594 // Need to write the version if zero; for version 3 on we set this to -1 to 595 // ignore it since we store this information in each key entry 596 if p.ConvergentEncryption && p.ConvergentVersion == 0 { 597 return true 598 } 599 600 if p.Keys[strconv.Itoa(p.LatestVersion)].HMACKey == nil || len(p.Keys[strconv.Itoa(p.LatestVersion)].HMACKey) == 0 { 601 return true 602 } 603 604 return false 605} 606 607func (p *Policy) Upgrade(ctx context.Context, storage logical.Storage) (retErr error) { 608 priorKey := p.Key 609 priorLatestVersion := p.LatestVersion 610 priorMinDecryptionVersion := p.MinDecryptionVersion 611 priorConvergentVersion := p.ConvergentVersion 612 var priorKeys keyEntryMap 613 614 if p.Keys != nil { 615 priorKeys = keyEntryMap{} 616 for k, v := range p.Keys { 617 priorKeys[k] = v 618 } 619 } 620 621 defer func() { 622 if retErr != nil { 623 p.Key = priorKey 624 p.LatestVersion = priorLatestVersion 625 p.MinDecryptionVersion = priorMinDecryptionVersion 626 p.ConvergentVersion = priorConvergentVersion 627 p.Keys = priorKeys 628 } 629 }() 630 631 persistNeeded := false 632 // Ensure we've moved from Key -> Keys 633 if p.Key != nil && len(p.Key) > 0 { 634 p.MigrateKeyToKeysMap() 635 persistNeeded = true 636 } 637 638 // With archiving, past assumptions about the length of the keys map are no 639 // longer valid 640 if p.LatestVersion == 0 && len(p.Keys) != 0 { 641 p.LatestVersion = len(p.Keys) 642 persistNeeded = true 643 } 644 645 // We disallow setting the version to 0, since they start at 1 since moving 646 // to rotate-able keys, so update if it's set to 0 647 if p.MinDecryptionVersion == 0 { 648 p.MinDecryptionVersion = 1 649 persistNeeded = true 650 } 651 652 // On first load after an upgrade, copy keys to the archive 653 if p.ArchiveVersion == 0 { 654 persistNeeded = true 655 } 656 657 if p.ConvergentEncryption && p.ConvergentVersion == 0 { 658 p.ConvergentVersion = 1 659 persistNeeded = true 660 } 661 662 if p.Keys[strconv.Itoa(p.LatestVersion)].HMACKey == nil || len(p.Keys[strconv.Itoa(p.LatestVersion)].HMACKey) == 0 { 663 entry := p.Keys[strconv.Itoa(p.LatestVersion)] 664 hmacKey, err := uuid.GenerateRandomBytes(32) 665 if err != nil { 666 return err 667 } 668 entry.HMACKey = hmacKey 669 p.Keys[strconv.Itoa(p.LatestVersion)] = entry 670 persistNeeded = true 671 } 672 673 if persistNeeded { 674 err := p.Persist(ctx, storage) 675 if err != nil { 676 return err 677 } 678 } 679 680 return nil 681} 682 683// DeriveKey is used to derive the encryption key that should be used depending 684// on the policy. If derivation is disabled the raw key is used and no context 685// is required, otherwise the KDF mode is used with the context to derive the 686// proper key. 687func (p *Policy) DeriveKey(context []byte, ver, numBytes int) ([]byte, error) { 688 // Fast-path non-derived keys 689 if !p.Derived { 690 return p.Keys[strconv.Itoa(ver)].Key, nil 691 } 692 693 if !p.Type.DerivationSupported() { 694 return nil, errutil.UserError{Err: fmt.Sprintf("derivation not supported for key type %v", p.Type)} 695 } 696 697 if p.Keys == nil || p.LatestVersion == 0 { 698 return nil, errutil.InternalError{Err: "unable to access the key; no key versions found"} 699 } 700 701 if ver <= 0 || ver > p.LatestVersion { 702 return nil, errutil.UserError{Err: "invalid key version"} 703 } 704 705 // Ensure a context is provided 706 if len(context) == 0 { 707 return nil, errutil.UserError{Err: "missing 'context' for key derivation; the key was created using a derived key, which means additional, per-request information must be included in order to perform operations with the key"} 708 } 709 710 switch p.KDF { 711 case Kdf_hmac_sha256_counter: 712 prf := kdf.HMACSHA256PRF 713 prfLen := kdf.HMACSHA256PRFLen 714 return kdf.CounterMode(prf, prfLen, p.Keys[strconv.Itoa(ver)].Key, context, 256) 715 716 case Kdf_hkdf_sha256: 717 reader := hkdf.New(sha256.New, p.Keys[strconv.Itoa(ver)].Key, nil, context) 718 derBytes := bytes.NewBuffer(nil) 719 derBytes.Grow(numBytes) 720 limReader := &io.LimitedReader{ 721 R: reader, 722 N: int64(numBytes), 723 } 724 725 switch p.Type { 726 case KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305: 727 n, err := derBytes.ReadFrom(limReader) 728 if err != nil { 729 return nil, errutil.InternalError{Err: fmt.Sprintf("error reading returned derived bytes: %v", err)} 730 } 731 if n != int64(numBytes) { 732 return nil, errutil.InternalError{Err: fmt.Sprintf("unable to read enough derived bytes, needed %d, got %d", numBytes, n)} 733 } 734 return derBytes.Bytes(), nil 735 736 case KeyType_ED25519: 737 // We use the limited reader containing the derived bytes as the 738 // "random" input to the generation function 739 _, pri, err := ed25519.GenerateKey(limReader) 740 if err != nil { 741 return nil, errutil.InternalError{Err: fmt.Sprintf("error generating derived key: %v", err)} 742 } 743 return pri, nil 744 745 default: 746 return nil, errutil.InternalError{Err: "unsupported key type for derivation"} 747 } 748 749 default: 750 return nil, errutil.InternalError{Err: "unsupported key derivation mode"} 751 } 752} 753 754func (p *Policy) convergentVersion(ver int) int { 755 if !p.ConvergentEncryption { 756 return 0 757 } 758 759 convergentVersion := p.ConvergentVersion 760 if convergentVersion == 0 { 761 // For some reason, not upgraded yet 762 convergentVersion = 1 763 } 764 currKey := p.Keys[strconv.Itoa(ver)] 765 if currKey.ConvergentVersion != 0 { 766 convergentVersion = currKey.ConvergentVersion 767 } 768 769 return convergentVersion 770} 771 772func (p *Policy) Encrypt(ver int, context, nonce []byte, value string) (string, error) { 773 if !p.Type.EncryptionSupported() { 774 return "", errutil.UserError{Err: fmt.Sprintf("message encryption not supported for key type %v", p.Type)} 775 } 776 777 // Decode the plaintext value 778 plaintext, err := base64.StdEncoding.DecodeString(value) 779 if err != nil { 780 return "", errutil.UserError{Err: err.Error()} 781 } 782 783 switch { 784 case ver == 0: 785 ver = p.LatestVersion 786 case ver < 0: 787 return "", errutil.UserError{Err: "requested version for encryption is negative"} 788 case ver > p.LatestVersion: 789 return "", errutil.UserError{Err: "requested version for encryption is higher than the latest key version"} 790 case ver < p.MinEncryptionVersion: 791 return "", errutil.UserError{Err: "requested version for encryption is less than the minimum encryption key version"} 792 } 793 794 var ciphertext []byte 795 796 switch p.Type { 797 case KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305: 798 hmacKey := context 799 800 var aead cipher.AEAD 801 var encKey []byte 802 var deriveHMAC bool 803 804 numBytes := 32 805 if p.convergentVersion(ver) > 2 { 806 deriveHMAC = true 807 numBytes = 64 808 } 809 key, err := p.DeriveKey(context, ver, numBytes) 810 if err != nil { 811 return "", err 812 } 813 814 if len(key) < numBytes { 815 return "", errutil.InternalError{Err: "could not derive key, length too small"} 816 } 817 818 encKey = key[:32] 819 if len(encKey) != 32 { 820 return "", errutil.InternalError{Err: "could not derive enc key, length not correct"} 821 } 822 if deriveHMAC { 823 hmacKey = key[32:] 824 if len(hmacKey) != 32 { 825 return "", errutil.InternalError{Err: "could not derive hmac key, length not correct"} 826 } 827 } 828 829 switch p.Type { 830 case KeyType_AES256_GCM96: 831 // Setup the cipher 832 aesCipher, err := aes.NewCipher(encKey) 833 if err != nil { 834 return "", errutil.InternalError{Err: err.Error()} 835 } 836 837 // Setup the GCM AEAD 838 gcm, err := cipher.NewGCM(aesCipher) 839 if err != nil { 840 return "", errutil.InternalError{Err: err.Error()} 841 } 842 843 aead = gcm 844 845 case KeyType_ChaCha20_Poly1305: 846 cha, err := chacha20poly1305.New(encKey) 847 if err != nil { 848 return "", errutil.InternalError{Err: err.Error()} 849 } 850 851 aead = cha 852 } 853 854 if p.ConvergentEncryption { 855 convergentVersion := p.convergentVersion(ver) 856 switch convergentVersion { 857 case 1: 858 if len(nonce) != aead.NonceSize() { 859 return "", errutil.UserError{Err: fmt.Sprintf("base64-decoded nonce must be %d bytes long when using convergent encryption with this key", aead.NonceSize())} 860 } 861 case 2, 3: 862 if len(hmacKey) == 0 { 863 return "", errutil.InternalError{Err: fmt.Sprintf("invalid hmac key length of zero")} 864 } 865 nonceHmac := hmac.New(sha256.New, hmacKey) 866 nonceHmac.Write(plaintext) 867 nonceSum := nonceHmac.Sum(nil) 868 nonce = nonceSum[:aead.NonceSize()] 869 default: 870 return "", errutil.InternalError{Err: fmt.Sprintf("unhandled convergent version %d", convergentVersion)} 871 } 872 } else { 873 // Compute random nonce 874 nonce, err = uuid.GenerateRandomBytes(aead.NonceSize()) 875 if err != nil { 876 return "", errutil.InternalError{Err: err.Error()} 877 } 878 } 879 880 // Encrypt and tag with AEAD 881 ciphertext = aead.Seal(nil, nonce, plaintext, nil) 882 883 // Place the encrypted data after the nonce 884 if !p.ConvergentEncryption || p.convergentVersion(ver) > 1 { 885 ciphertext = append(nonce, ciphertext...) 886 } 887 888 case KeyType_RSA2048, KeyType_RSA4096: 889 key := p.Keys[strconv.Itoa(ver)].RSAKey 890 ciphertext, err = rsa.EncryptOAEP(sha256.New(), rand.Reader, &key.PublicKey, plaintext, nil) 891 if err != nil { 892 return "", errutil.InternalError{Err: fmt.Sprintf("failed to RSA encrypt the plaintext: %v", err)} 893 } 894 895 default: 896 return "", errutil.InternalError{Err: fmt.Sprintf("unsupported key type %v", p.Type)} 897 } 898 899 // Convert to base64 900 encoded := base64.StdEncoding.EncodeToString(ciphertext) 901 902 // Prepend some information 903 encoded = p.getVersionPrefix(ver) + encoded 904 905 return encoded, nil 906} 907 908func (p *Policy) Decrypt(context, nonce []byte, value string) (string, error) { 909 if !p.Type.DecryptionSupported() { 910 return "", errutil.UserError{Err: fmt.Sprintf("message decryption not supported for key type %v", p.Type)} 911 } 912 913 tplParts, err := p.getTemplateParts() 914 if err != nil { 915 return "", err 916 } 917 918 // Verify the prefix 919 if !strings.HasPrefix(value, tplParts[0]) { 920 return "", errutil.UserError{Err: "invalid ciphertext: no prefix"} 921 } 922 923 splitVerCiphertext := strings.SplitN(strings.TrimPrefix(value, tplParts[0]), tplParts[1], 2) 924 if len(splitVerCiphertext) != 2 { 925 return "", errutil.UserError{Err: "invalid ciphertext: wrong number of fields"} 926 } 927 928 ver, err := strconv.Atoi(splitVerCiphertext[0]) 929 if err != nil { 930 return "", errutil.UserError{Err: "invalid ciphertext: version number could not be decoded"} 931 } 932 933 if ver == 0 { 934 // Compatibility mode with initial implementation, where keys start at 935 // zero 936 ver = 1 937 } 938 939 if ver > p.LatestVersion { 940 return "", errutil.UserError{Err: "invalid ciphertext: version is too new"} 941 } 942 943 if p.MinDecryptionVersion > 0 && ver < p.MinDecryptionVersion { 944 return "", errutil.UserError{Err: ErrTooOld} 945 } 946 947 convergentVersion := p.convergentVersion(ver) 948 if convergentVersion == 1 && (nonce == nil || len(nonce) == 0) { 949 return "", errutil.UserError{Err: "invalid convergent nonce supplied"} 950 } 951 952 // Decode the base64 953 decoded, err := base64.StdEncoding.DecodeString(splitVerCiphertext[1]) 954 if err != nil { 955 return "", errutil.UserError{Err: "invalid ciphertext: could not decode base64"} 956 } 957 958 var plain []byte 959 960 switch p.Type { 961 case KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305: 962 var aead cipher.AEAD 963 964 encKey, err := p.DeriveKey(context, ver, 32) 965 if err != nil { 966 return "", err 967 } 968 969 if len(encKey) != 32 { 970 return "", errutil.InternalError{Err: "could not derive enc key, length not correct"} 971 } 972 973 switch p.Type { 974 case KeyType_AES256_GCM96: 975 // Setup the cipher 976 aesCipher, err := aes.NewCipher(encKey) 977 if err != nil { 978 return "", errutil.InternalError{Err: err.Error()} 979 } 980 981 // Setup the GCM AEAD 982 gcm, err := cipher.NewGCM(aesCipher) 983 if err != nil { 984 return "", errutil.InternalError{Err: err.Error()} 985 } 986 987 aead = gcm 988 989 case KeyType_ChaCha20_Poly1305: 990 cha, err := chacha20poly1305.New(encKey) 991 if err != nil { 992 return "", errutil.InternalError{Err: err.Error()} 993 } 994 995 aead = cha 996 } 997 998 if len(decoded) < aead.NonceSize() { 999 return "", errutil.UserError{Err: "invalid ciphertext length"} 1000 } 1001 1002 // Extract the nonce and ciphertext 1003 var ciphertext []byte 1004 if p.ConvergentEncryption && convergentVersion == 1 { 1005 ciphertext = decoded 1006 } else { 1007 nonce = decoded[:aead.NonceSize()] 1008 ciphertext = decoded[aead.NonceSize():] 1009 } 1010 1011 // Verify and Decrypt 1012 plain, err = aead.Open(nil, nonce, ciphertext, nil) 1013 if err != nil { 1014 return "", errutil.UserError{Err: "invalid ciphertext: unable to decrypt"} 1015 } 1016 1017 case KeyType_RSA2048, KeyType_RSA4096: 1018 key := p.Keys[strconv.Itoa(ver)].RSAKey 1019 plain, err = rsa.DecryptOAEP(sha256.New(), rand.Reader, key, decoded, nil) 1020 if err != nil { 1021 return "", errutil.InternalError{Err: fmt.Sprintf("failed to RSA decrypt the ciphertext: %v", err)} 1022 } 1023 1024 default: 1025 return "", errutil.InternalError{Err: fmt.Sprintf("unsupported key type %v", p.Type)} 1026 } 1027 1028 return base64.StdEncoding.EncodeToString(plain), nil 1029} 1030 1031func (p *Policy) HMACKey(version int) ([]byte, error) { 1032 switch { 1033 case version < 0: 1034 return nil, fmt.Errorf("key version does not exist (cannot be negative)") 1035 case version > p.LatestVersion: 1036 return nil, fmt.Errorf("key version does not exist; latest key version is %d", p.LatestVersion) 1037 } 1038 1039 if p.Keys[strconv.Itoa(version)].HMACKey == nil { 1040 return nil, fmt.Errorf("no HMAC key exists for that key version") 1041 } 1042 1043 return p.Keys[strconv.Itoa(version)].HMACKey, nil 1044} 1045 1046func (p *Policy) Sign(ver int, context, input []byte, hashAlgorithm HashType, sigAlgorithm string, marshaling MarshalingType) (*SigningResult, error) { 1047 if !p.Type.SigningSupported() { 1048 return nil, fmt.Errorf("message signing not supported for key type %v", p.Type) 1049 } 1050 1051 switch { 1052 case ver == 0: 1053 ver = p.LatestVersion 1054 case ver < 0: 1055 return nil, errutil.UserError{Err: "requested version for signing is negative"} 1056 case ver > p.LatestVersion: 1057 return nil, errutil.UserError{Err: "requested version for signing is higher than the latest key version"} 1058 case p.MinEncryptionVersion > 0 && ver < p.MinEncryptionVersion: 1059 return nil, errutil.UserError{Err: "requested version for signing is less than the minimum encryption key version"} 1060 } 1061 1062 var sig []byte 1063 var pubKey []byte 1064 var err error 1065 switch p.Type { 1066 case KeyType_ECDSA_P256: 1067 curveBits := 256 1068 keyParams := p.Keys[strconv.Itoa(ver)] 1069 key := &ecdsa.PrivateKey{ 1070 PublicKey: ecdsa.PublicKey{ 1071 Curve: elliptic.P256(), 1072 X: keyParams.EC_X, 1073 Y: keyParams.EC_Y, 1074 }, 1075 D: keyParams.EC_D, 1076 } 1077 1078 r, s, err := ecdsa.Sign(rand.Reader, key, input) 1079 if err != nil { 1080 return nil, err 1081 } 1082 1083 switch marshaling { 1084 case MarshalingTypeASN1: 1085 // This is used by openssl and X.509 1086 sig, err = asn1.Marshal(ecdsaSignature{ 1087 R: r, 1088 S: s, 1089 }) 1090 if err != nil { 1091 return nil, err 1092 } 1093 1094 case MarshalingTypeJWS: 1095 // This is used by JWS 1096 1097 // First we have to get the length of the curve in bytes. Although 1098 // we only support 256 now, we'll do this in an agnostic way so we 1099 // can reuse this marshaling if we support e.g. 521. Getting the 1100 // number of bytes without rounding up would be 65.125 so we need 1101 // to add one in that case. 1102 keyLen := curveBits / 8 1103 if curveBits%8 > 0 { 1104 keyLen++ 1105 } 1106 1107 // Now create the output array 1108 sig = make([]byte, keyLen*2) 1109 rb := r.Bytes() 1110 sb := s.Bytes() 1111 copy(sig[keyLen-len(rb):], rb) 1112 copy(sig[2*keyLen-len(sb):], sb) 1113 1114 default: 1115 return nil, errutil.UserError{Err: "requested marshaling type is invalid"} 1116 } 1117 1118 case KeyType_ED25519: 1119 var key ed25519.PrivateKey 1120 1121 if p.Derived { 1122 // Derive the key that should be used 1123 var err error 1124 key, err = p.DeriveKey(context, ver, 32) 1125 if err != nil { 1126 return nil, errutil.InternalError{Err: fmt.Sprintf("error deriving key: %v", err)} 1127 } 1128 pubKey = key.Public().(ed25519.PublicKey) 1129 } else { 1130 key = ed25519.PrivateKey(p.Keys[strconv.Itoa(ver)].Key) 1131 } 1132 1133 // Per docs, do not pre-hash ed25519; it does two passes and performs 1134 // its own hashing 1135 sig, err = key.Sign(rand.Reader, input, crypto.Hash(0)) 1136 if err != nil { 1137 return nil, err 1138 } 1139 1140 case KeyType_RSA2048, KeyType_RSA4096: 1141 key := p.Keys[strconv.Itoa(ver)].RSAKey 1142 1143 var algo crypto.Hash 1144 switch hashAlgorithm { 1145 case HashTypeSHA1: 1146 algo = crypto.SHA1 1147 case HashTypeSHA2224: 1148 algo = crypto.SHA224 1149 case HashTypeSHA2256: 1150 algo = crypto.SHA256 1151 case HashTypeSHA2384: 1152 algo = crypto.SHA384 1153 case HashTypeSHA2512: 1154 algo = crypto.SHA512 1155 default: 1156 return nil, errutil.InternalError{Err: "unsupported hash algorithm"} 1157 } 1158 1159 if sigAlgorithm == "" { 1160 sigAlgorithm = "pss" 1161 } 1162 1163 switch sigAlgorithm { 1164 case "pss": 1165 sig, err = rsa.SignPSS(rand.Reader, key, algo, input, nil) 1166 if err != nil { 1167 return nil, err 1168 } 1169 case "pkcs1v15": 1170 sig, err = rsa.SignPKCS1v15(rand.Reader, key, algo, input) 1171 if err != nil { 1172 return nil, err 1173 } 1174 default: 1175 return nil, errutil.InternalError{Err: fmt.Sprintf("unsupported rsa signature algorithm %s", sigAlgorithm)} 1176 } 1177 1178 default: 1179 return nil, fmt.Errorf("unsupported key type %v", p.Type) 1180 } 1181 1182 // Convert to base64 1183 var encoded string 1184 switch marshaling { 1185 case MarshalingTypeASN1: 1186 encoded = base64.StdEncoding.EncodeToString(sig) 1187 case MarshalingTypeJWS: 1188 encoded = base64.RawURLEncoding.EncodeToString(sig) 1189 } 1190 res := &SigningResult{ 1191 Signature: p.getVersionPrefix(ver) + encoded, 1192 PublicKey: pubKey, 1193 } 1194 1195 return res, nil 1196} 1197 1198func (p *Policy) VerifySignature(context, input []byte, hashAlgorithm HashType, sigAlgorithm string, marshaling MarshalingType, sig string) (bool, error) { 1199 if !p.Type.SigningSupported() { 1200 return false, errutil.UserError{Err: fmt.Sprintf("message verification not supported for key type %v", p.Type)} 1201 } 1202 1203 tplParts, err := p.getTemplateParts() 1204 if err != nil { 1205 return false, err 1206 } 1207 1208 // Verify the prefix 1209 if !strings.HasPrefix(sig, tplParts[0]) { 1210 return false, errutil.UserError{Err: "invalid signature: no prefix"} 1211 } 1212 1213 splitVerSig := strings.SplitN(strings.TrimPrefix(sig, tplParts[0]), tplParts[1], 2) 1214 if len(splitVerSig) != 2 { 1215 return false, errutil.UserError{Err: "invalid signature: wrong number of fields"} 1216 } 1217 1218 ver, err := strconv.Atoi(splitVerSig[0]) 1219 if err != nil { 1220 return false, errutil.UserError{Err: "invalid signature: version number could not be decoded"} 1221 } 1222 1223 if ver > p.LatestVersion { 1224 return false, errutil.UserError{Err: "invalid signature: version is too new"} 1225 } 1226 1227 if p.MinDecryptionVersion > 0 && ver < p.MinDecryptionVersion { 1228 return false, errutil.UserError{Err: ErrTooOld} 1229 } 1230 1231 var sigBytes []byte 1232 switch marshaling { 1233 case MarshalingTypeASN1: 1234 sigBytes, err = base64.StdEncoding.DecodeString(splitVerSig[1]) 1235 case MarshalingTypeJWS: 1236 sigBytes, err = base64.RawURLEncoding.DecodeString(splitVerSig[1]) 1237 default: 1238 return false, errutil.UserError{Err: "requested marshaling type is invalid"} 1239 } 1240 if err != nil { 1241 return false, errutil.UserError{Err: "invalid base64 signature value"} 1242 } 1243 1244 switch p.Type { 1245 case KeyType_ECDSA_P256: 1246 var ecdsaSig ecdsaSignature 1247 1248 switch marshaling { 1249 case MarshalingTypeASN1: 1250 rest, err := asn1.Unmarshal(sigBytes, &ecdsaSig) 1251 if err != nil { 1252 return false, errutil.UserError{Err: "supplied signature is invalid"} 1253 } 1254 if rest != nil && len(rest) != 0 { 1255 return false, errutil.UserError{Err: "supplied signature contains extra data"} 1256 } 1257 1258 case MarshalingTypeJWS: 1259 paramLen := len(sigBytes) / 2 1260 rb := sigBytes[:paramLen] 1261 sb := sigBytes[paramLen:] 1262 ecdsaSig.R = new(big.Int) 1263 ecdsaSig.R.SetBytes(rb) 1264 ecdsaSig.S = new(big.Int) 1265 ecdsaSig.S.SetBytes(sb) 1266 } 1267 1268 keyParams := p.Keys[strconv.Itoa(ver)] 1269 key := &ecdsa.PublicKey{ 1270 Curve: elliptic.P256(), 1271 X: keyParams.EC_X, 1272 Y: keyParams.EC_Y, 1273 } 1274 1275 return ecdsa.Verify(key, input, ecdsaSig.R, ecdsaSig.S), nil 1276 1277 case KeyType_ED25519: 1278 var key ed25519.PrivateKey 1279 1280 if p.Derived { 1281 // Derive the key that should be used 1282 var err error 1283 key, err = p.DeriveKey(context, ver, 32) 1284 if err != nil { 1285 return false, errutil.InternalError{Err: fmt.Sprintf("error deriving key: %v", err)} 1286 } 1287 } else { 1288 key = ed25519.PrivateKey(p.Keys[strconv.Itoa(ver)].Key) 1289 } 1290 1291 return ed25519.Verify(key.Public().(ed25519.PublicKey), input, sigBytes), nil 1292 1293 case KeyType_RSA2048, KeyType_RSA4096: 1294 key := p.Keys[strconv.Itoa(ver)].RSAKey 1295 1296 var algo crypto.Hash 1297 switch hashAlgorithm { 1298 case HashTypeSHA1: 1299 algo = crypto.SHA1 1300 case HashTypeSHA2224: 1301 algo = crypto.SHA224 1302 case HashTypeSHA2256: 1303 algo = crypto.SHA256 1304 case HashTypeSHA2384: 1305 algo = crypto.SHA384 1306 case HashTypeSHA2512: 1307 algo = crypto.SHA512 1308 default: 1309 return false, errutil.InternalError{Err: "unsupported hash algorithm"} 1310 } 1311 1312 if sigAlgorithm == "" { 1313 sigAlgorithm = "pss" 1314 } 1315 1316 switch sigAlgorithm { 1317 case "pss": 1318 err = rsa.VerifyPSS(&key.PublicKey, algo, input, sigBytes, nil) 1319 case "pkcs1v15": 1320 err = rsa.VerifyPKCS1v15(&key.PublicKey, algo, input, sigBytes) 1321 default: 1322 return false, errutil.InternalError{Err: fmt.Sprintf("unsupported rsa signature algorithm %s", sigAlgorithm)} 1323 } 1324 1325 return err == nil, nil 1326 1327 default: 1328 return false, errutil.InternalError{Err: fmt.Sprintf("unsupported key type %v", p.Type)} 1329 } 1330} 1331 1332func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) (retErr error) { 1333 priorLatestVersion := p.LatestVersion 1334 priorMinDecryptionVersion := p.MinDecryptionVersion 1335 var priorKeys keyEntryMap 1336 1337 if p.Keys != nil { 1338 priorKeys = keyEntryMap{} 1339 for k, v := range p.Keys { 1340 priorKeys[k] = v 1341 } 1342 } 1343 1344 defer func() { 1345 if retErr != nil { 1346 p.LatestVersion = priorLatestVersion 1347 p.MinDecryptionVersion = priorMinDecryptionVersion 1348 p.Keys = priorKeys 1349 } 1350 }() 1351 1352 if p.Keys == nil { 1353 // This is an initial key rotation when generating a new policy. We 1354 // don't need to call migrate here because if we've called getPolicy to 1355 // get the policy in the first place it will have been run. 1356 p.Keys = keyEntryMap{} 1357 } 1358 1359 p.LatestVersion += 1 1360 now := time.Now() 1361 entry := KeyEntry{ 1362 CreationTime: now, 1363 DeprecatedCreationTime: now.Unix(), 1364 } 1365 1366 hmacKey, err := uuid.GenerateRandomBytes(32) 1367 if err != nil { 1368 return err 1369 } 1370 entry.HMACKey = hmacKey 1371 1372 switch p.Type { 1373 case KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305: 1374 // Generate a 256bit key 1375 newKey, err := uuid.GenerateRandomBytes(32) 1376 if err != nil { 1377 return err 1378 } 1379 entry.Key = newKey 1380 1381 case KeyType_ECDSA_P256: 1382 privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 1383 if err != nil { 1384 return err 1385 } 1386 entry.EC_D = privKey.D 1387 entry.EC_X = privKey.X 1388 entry.EC_Y = privKey.Y 1389 derBytes, err := x509.MarshalPKIXPublicKey(privKey.Public()) 1390 if err != nil { 1391 return errwrap.Wrapf("error marshaling public key: {{err}}", err) 1392 } 1393 pemBlock := &pem.Block{ 1394 Type: "PUBLIC KEY", 1395 Bytes: derBytes, 1396 } 1397 pemBytes := pem.EncodeToMemory(pemBlock) 1398 if pemBytes == nil || len(pemBytes) == 0 { 1399 return fmt.Errorf("error PEM-encoding public key") 1400 } 1401 entry.FormattedPublicKey = string(pemBytes) 1402 1403 case KeyType_ED25519: 1404 pub, pri, err := ed25519.GenerateKey(rand.Reader) 1405 if err != nil { 1406 return err 1407 } 1408 entry.Key = pri 1409 entry.FormattedPublicKey = base64.StdEncoding.EncodeToString(pub) 1410 1411 case KeyType_RSA2048, KeyType_RSA4096: 1412 bitSize := 2048 1413 if p.Type == KeyType_RSA4096 { 1414 bitSize = 4096 1415 } 1416 1417 entry.RSAKey, err = rsa.GenerateKey(rand.Reader, bitSize) 1418 if err != nil { 1419 return err 1420 } 1421 } 1422 1423 if p.ConvergentEncryption { 1424 if p.ConvergentVersion == -1 || p.ConvergentVersion > 1 { 1425 entry.ConvergentVersion = currentConvergentVersion 1426 } 1427 } 1428 1429 p.Keys[strconv.Itoa(p.LatestVersion)] = entry 1430 1431 // This ensures that with new key creations min decryption version is set 1432 // to 1 rather than the int default of 0, since keys start at 1 (either 1433 // fresh or after migration to the key map) 1434 if p.MinDecryptionVersion == 0 { 1435 p.MinDecryptionVersion = 1 1436 } 1437 1438 return p.Persist(ctx, storage) 1439} 1440 1441func (p *Policy) MigrateKeyToKeysMap() { 1442 now := time.Now() 1443 p.Keys = keyEntryMap{ 1444 "1": KeyEntry{ 1445 Key: p.Key, 1446 CreationTime: now, 1447 DeprecatedCreationTime: now.Unix(), 1448 }, 1449 } 1450 p.Key = nil 1451} 1452 1453// Backup should be called with an exclusive lock held on the policy 1454func (p *Policy) Backup(ctx context.Context, storage logical.Storage) (out string, retErr error) { 1455 if !p.Exportable { 1456 return "", fmt.Errorf("exporting is disallowed on the policy") 1457 } 1458 1459 if !p.AllowPlaintextBackup { 1460 return "", fmt.Errorf("plaintext backup is disallowed on the policy") 1461 } 1462 1463 priorBackupInfo := p.BackupInfo 1464 1465 defer func() { 1466 if retErr != nil { 1467 p.BackupInfo = priorBackupInfo 1468 } 1469 }() 1470 1471 // Create a record of this backup operation in the policy 1472 p.BackupInfo = &BackupInfo{ 1473 Time: time.Now(), 1474 Version: p.LatestVersion, 1475 } 1476 err := p.Persist(ctx, storage) 1477 if err != nil { 1478 return "", errwrap.Wrapf("failed to persist policy with backup info: {{err}}", err) 1479 } 1480 1481 // Load the archive only after persisting the policy as the archive can get 1482 // adjusted while persisting the policy 1483 archivedKeys, err := p.LoadArchive(ctx, storage) 1484 if err != nil { 1485 return "", err 1486 } 1487 1488 keyData := &KeyData{ 1489 Policy: p, 1490 ArchivedKeys: archivedKeys, 1491 } 1492 1493 encodedBackup, err := jsonutil.EncodeJSON(keyData) 1494 if err != nil { 1495 return "", err 1496 } 1497 1498 return base64.StdEncoding.EncodeToString(encodedBackup), nil 1499} 1500 1501func (p *Policy) getTemplateParts() ([]string, error) { 1502 partsRaw, ok := p.versionPrefixCache.Load("template-parts") 1503 if ok { 1504 return partsRaw.([]string), nil 1505 } 1506 1507 template := p.VersionTemplate 1508 if template == "" { 1509 template = DefaultVersionTemplate 1510 } 1511 1512 tplParts := strings.Split(template, "{{version}}") 1513 if len(tplParts) != 2 { 1514 return nil, errutil.InternalError{Err: "error parsing version template"} 1515 } 1516 1517 p.versionPrefixCache.Store("template-parts", tplParts) 1518 return tplParts, nil 1519} 1520 1521func (p *Policy) getVersionPrefix(ver int) string { 1522 prefixRaw, ok := p.versionPrefixCache.Load(ver) 1523 if ok { 1524 return prefixRaw.(string) 1525 } 1526 1527 template := p.VersionTemplate 1528 if template == "" { 1529 template = DefaultVersionTemplate 1530 } 1531 1532 prefix := strings.Replace(template, "{{version}}", strconv.Itoa(ver), -1) 1533 p.versionPrefixCache.Store(ver, prefix) 1534 1535 return prefix 1536} 1537