1// Copyright 2019 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14// 15//////////////////////////////////////////////////////////////////////////////// 16 17package keyset 18 19import ( 20 "io" 21 22 "google.golang.org/protobuf/encoding/protojson" 23 "google.golang.org/protobuf/proto" 24 25 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 26) 27 28// JSONReader deserializes a keyset from json format. 29type JSONReader struct { 30 r io.Reader 31 j *protojson.UnmarshalOptions 32} 33 34// NewJSONReader returns new JSONReader that will read from r. 35func NewJSONReader(r io.Reader) *JSONReader { 36 return &JSONReader{ 37 r: r, 38 j: &protojson.UnmarshalOptions{}, 39 } 40} 41 42// Read parses a (cleartext) keyset from the underlying io.Reader. 43func (bkr *JSONReader) Read() (*tinkpb.Keyset, error) { 44 keyset := &tinkpb.Keyset{} 45 46 if err := bkr.readJSON(bkr.r, keyset); err != nil { 47 return nil, err 48 } 49 return keyset, nil 50} 51 52// ReadEncrypted parses an EncryptedKeyset from the underlying io.Reader. 53func (bkr *JSONReader) ReadEncrypted() (*tinkpb.EncryptedKeyset, error) { 54 keyset := &tinkpb.EncryptedKeyset{} 55 56 if err := bkr.readJSON(bkr.r, keyset); err != nil { 57 return nil, err 58 } 59 return keyset, nil 60} 61 62func (bkr *JSONReader) readJSON(r io.Reader, msg proto.Message) error { 63 b, err := io.ReadAll(r) 64 if err != nil { 65 return err 66 } 67 return bkr.j.Unmarshal(b, msg) 68} 69 70// JSONWriter serializes a keyset into json format. 71type JSONWriter struct { 72 w io.Writer 73 j *protojson.MarshalOptions 74} 75 76// NewJSONWriter returns a new JSONWriter that will write to w. 77func NewJSONWriter(w io.Writer) *JSONWriter { 78 return &JSONWriter{ 79 w: w, 80 j: &protojson.MarshalOptions{ 81 EmitUnpopulated: true, 82 Indent: "", 83 }, 84 } 85} 86 87// Write writes the keyset to the underlying io.Writer. 88func (bkw *JSONWriter) Write(keyset *tinkpb.Keyset) error { 89 return bkw.writeJSON(bkw.w, keyset) 90} 91 92// WriteEncrypted writes the encrypted keyset to the underlying io.Writer. 93func (bkw *JSONWriter) WriteEncrypted(keyset *tinkpb.EncryptedKeyset) error { 94 return bkw.writeJSON(bkw.w, keyset) 95} 96 97func (bkw *JSONWriter) writeJSON(w io.Writer, msg proto.Message) error { 98 b, err := bkw.j.Marshal(msg) 99 if err != nil { 100 return err 101 } 102 _, err = w.Write(b) 103 return err 104} 105