func (b *backend) pathPolicyWrite( req *logical.Request, d *framework.FieldData) (*logical.Response, error) { name := d.Get("name").(string) derived := d.Get("derived").(bool) convergent := d.Get("convergent_encryption").(bool) keyType := d.Get("type").(string) if !derived && convergent { return logical.ErrorResponse("convergent encryption requires derivation to be enabled"), nil } polReq := keysutil.PolicyRequest{ Storage: req.Storage, Name: name, Derived: derived, Convergent: convergent, } switch keyType { case "aes256-gcm96": polReq.KeyType = keysutil.KeyType_AES256_GCM96 case "ecdsa-p256": polReq.KeyType = keysutil.KeyType_ECDSA_P256 default: return logical.ErrorResponse(fmt.Sprintf("unknown key type %v", keyType)), logical.ErrInvalidRequest } p, lock, upserted, err := b.lm.GetPolicyUpsert(polReq) if lock != nil { defer lock.RUnlock() } if err != nil { return nil, err } if p == nil { return nil, fmt.Errorf("error generating key: returned policy was nil") } resp := &logical.Response{} if !upserted { resp.AddWarning(fmt.Sprintf("key %s already existed", name)) } return nil, nil }
func (b *backend) pathEncryptWrite( req *logical.Request, d *framework.FieldData) (*logical.Response, error) { name := d.Get("name").(string) valueRaw, ok := d.GetOk("plaintext") if !ok { return logical.ErrorResponse("missing plaintext to encrypt"), logical.ErrInvalidRequest } value := valueRaw.(string) // Decode the context if any contextRaw := d.Get("context").(string) var context []byte var err error if len(contextRaw) != 0 { context, err = base64.StdEncoding.DecodeString(contextRaw) if err != nil { return logical.ErrorResponse("failed to base64-decode context"), logical.ErrInvalidRequest } } // Decode the nonce if any nonceRaw := d.Get("nonce").(string) var nonce []byte if len(nonceRaw) != 0 { nonce, err = base64.StdEncoding.DecodeString(nonceRaw) if err != nil { return logical.ErrorResponse("failed to base64-decode nonce"), logical.ErrInvalidRequest } } // Get the policy var p *keysutil.Policy var lock *sync.RWMutex var upserted bool if req.Operation == logical.CreateOperation { convergent := d.Get("convergent_encryption").(bool) if convergent && len(context) == 0 { return logical.ErrorResponse("convergent encryption requires derivation to be enabled, so context is required"), nil } polReq := keysutil.PolicyRequest{ Storage: req.Storage, Name: name, Derived: len(context) != 0, Convergent: convergent, } keyType := d.Get("type").(string) switch keyType { case "aes256-gcm96": polReq.KeyType = keysutil.KeyType_AES256_GCM96 case "ecdsa-p256": return logical.ErrorResponse(fmt.Sprintf("key type %v not supported for this operation", keyType)), logical.ErrInvalidRequest default: return logical.ErrorResponse(fmt.Sprintf("unknown key type %v", keyType)), logical.ErrInvalidRequest } p, lock, upserted, err = b.lm.GetPolicyUpsert(polReq) } else { p, lock, err = b.lm.GetPolicyShared(req.Storage, name) } if lock != nil { defer lock.RUnlock() } if err != nil { return nil, err } if p == nil { return logical.ErrorResponse("policy not found"), logical.ErrInvalidRequest } ciphertext, err := p.Encrypt(context, nonce, value) if err != nil { switch err.(type) { case errutil.UserError: return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest case errutil.InternalError: return nil, err default: return nil, err } } if ciphertext == "" { return nil, fmt.Errorf("empty ciphertext returned") } // Generate the response resp := &logical.Response{ Data: map[string]interface{}{ "ciphertext": ciphertext, }, } if req.Operation == logical.CreateOperation && !upserted { resp.AddWarning("Attempted creation of the key during the encrypt operation, but it was created beforehand") } return resp, nil }