github.com/Psiphon-Labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/common/protocol/signer/main.go (about) 1 /* 2 * Copyright (c) 2019, Psiphon Inc. 3 * All rights reserved. 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package main 21 22 import ( 23 "flag" 24 "fmt" 25 "os" 26 27 "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/protocol" 28 ) 29 30 func main() { 31 32 var publicKey string 33 flag.StringVar(&publicKey, "public-key", "", "server entry signing public key") 34 35 var privateKey string 36 flag.StringVar(&privateKey, "private-key", "", "server entry signing private key") 37 38 var encodedServerEntry string 39 flag.StringVar(&encodedServerEntry, "server-entry", "", "encoded server entry") 40 41 flag.Usage = func() { 42 fmt.Fprintf(os.Stderr, 43 "Usage:\n\n"+ 44 "%s <flags> generate generates and outputs a signing key pair\n"+ 45 "%s <flags> sign signs a specified server entry with a specified key pair\n\n", 46 os.Args[0], os.Args[0]) 47 flag.PrintDefaults() 48 } 49 50 flag.Parse() 51 52 args := flag.Args() 53 54 var command string 55 if len(args) >= 1 { 56 command = args[0] 57 } 58 59 envPublicKey := os.Getenv("SIGNER_PUBLIC_KEY") 60 if envPublicKey != "" { 61 publicKey = envPublicKey 62 } 63 64 envPrivateKey := os.Getenv("SIGNER_PRIVATE_KEY") 65 if envPrivateKey != "" { 66 privateKey = envPrivateKey 67 } 68 69 envEncodedServerEntry := os.Getenv("SIGNER_SERVER_ENTRY") 70 if envEncodedServerEntry != "" { 71 encodedServerEntry = envEncodedServerEntry 72 } 73 74 var err error 75 switch command { 76 case "generate": 77 err = generate() 78 case "sign": 79 if publicKey == "" || privateKey == "" || encodedServerEntry == "" { 80 flag.Usage() 81 os.Exit(1) 82 } 83 err = sign(publicKey, privateKey, encodedServerEntry) 84 default: 85 flag.Usage() 86 os.Exit(1) 87 } 88 89 if err != nil { 90 fmt.Printf("%s\n", err) 91 os.Exit(1) 92 } 93 } 94 95 func generate() error { 96 97 publicKey, privateKey, err := protocol.NewServerEntrySignatureKeyPair() 98 if err != nil { 99 return fmt.Errorf("generate key pair failed: %s", err) 100 } 101 102 fmt.Printf("public-key: %s\nprivate-key: %s\n\n", publicKey, privateKey) 103 104 return nil 105 } 106 107 func sign(publicKey, privateKey, encodedServerEntry string) error { 108 109 serverEntryFields, err := protocol.DecodeServerEntryFields(encodedServerEntry, "", "") 110 if err != nil { 111 return fmt.Errorf("decode server entry failed: %s", err) 112 } 113 114 err = serverEntryFields.AddSignature(publicKey, privateKey) 115 if err != nil { 116 return fmt.Errorf("add signature failed: %s", err) 117 } 118 119 encodedSignedServerEntry, err := protocol.EncodeServerEntryFields(serverEntryFields) 120 if err != nil { 121 return fmt.Errorf("encode server entry failed: %s", err) 122 } 123 124 fmt.Printf("%s\n\n", encodedSignedServerEntry) 125 126 return nil 127 }