github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/creds/jwk.go (about) 1 // Copyright 2019 Dolthub, Inc. 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 package creds 16 17 import ( 18 "encoding/base64" 19 "encoding/json" 20 "io" 21 "path/filepath" 22 23 "github.com/dolthub/dolt/go/libraries/utils/filesys" 24 "github.com/dolthub/dolt/go/libraries/utils/iohelp" 25 ) 26 27 const ( 28 JWKFileExtension = ".jwk" 29 ed25519Crv = "Ed25519" 30 kty = "OKP" 31 ) 32 33 type jwkData struct { 34 D *string `json:"d"` 35 X *string `json:"x"` 36 Kty string `json:"kty"` 37 Crv string `json:"crv"` 38 } 39 40 func JWKCredSerialize(dc DoltCreds) ([]byte, error) { 41 if !dc.IsPubKeyValid() { 42 panic("public key missing or invalid. This is a bug. Should be validated before calling") 43 } 44 45 pubKeyStr := base64.URLEncoding.EncodeToString(dc.PubKey) 46 47 var privKeyStr string 48 if dc.HasPrivKey() { 49 if !dc.IsPrivKeyValid() { 50 panic("Invalid private key. This is a bug. Should be validated before calling") 51 } 52 53 privKeyStr = base64.URLEncoding.EncodeToString(dc.PrivKey) 54 } 55 56 toSerialize := jwkData{&pubKeyStr, &privKeyStr, kty, ed25519Crv} 57 data, err := json.Marshal(toSerialize) 58 59 if err != nil { 60 return nil, err 61 } 62 63 return data, nil 64 } 65 66 func JWKCredsDeserialize(data []byte) (DoltCreds, error) { 67 var jwk jwkData 68 err := json.Unmarshal(data, &jwk) 69 70 if err == nil { 71 var pub, priv []byte 72 pub, err = base64.URLEncoding.DecodeString(*jwk.D) 73 74 if err == nil { 75 if jwk.X != nil { 76 priv, err = base64.URLEncoding.DecodeString(*jwk.X) 77 } 78 79 if err == nil { 80 kid := PubKeyToKID(pub) 81 return DoltCreds{pub, priv, kid}, nil 82 } 83 } 84 } 85 86 return DoltCreds{}, err 87 } 88 89 func JWKCredsWrite(wr io.Writer, dc DoltCreds) error { 90 data, err := JWKCredSerialize(dc) 91 92 if err != nil { 93 return err 94 } 95 96 return iohelp.WriteAll(wr, data) 97 } 98 99 func JWKCredsRead(rd io.Reader) (DoltCreds, error) { 100 data, err := io.ReadAll(rd) 101 102 if err != nil { 103 return DoltCreds{}, err 104 } 105 106 return JWKCredsDeserialize(data) 107 } 108 109 func JWKCredsWriteToDir(fs filesys.Filesys, dir string, dc DoltCreds) (string, error) { 110 outFile := filepath.Join(dir, dc.KeyIDBase32Str()+JWKFileExtension) 111 wr, err := fs.OpenForWrite(outFile, 0600) 112 113 if err != nil { 114 return "", err 115 } 116 117 err = JWKCredsWrite(wr, dc) 118 if err == nil { 119 err = wr.Close() 120 } else { 121 wr.Close() 122 } 123 124 return outFile, err 125 } 126 127 func JWKCredsReadFromFile(fs filesys.Filesys, path string) (DoltCreds, error) { 128 rd, err := fs.OpenForRead(path) 129 130 if err != nil { 131 return DoltCreds{}, err 132 } 133 134 defer rd.Close() 135 return JWKCredsRead(rd) 136 }