...

Source file src/golang.conradwood.net/go-easyops/common/sign_verify.go

Documentation: golang.conradwood.net/go-easyops/common

     1  package common
     2  
     3  import (
     4  	ed "crypto/ed25519"
     5  	"fmt"
     6  	"github.com/golang/protobuf/proto"
     7  	pb "golang.conradwood.net/apis/auth"
     8  	"io/ioutil"
     9  	"os"
    10  )
    11  
    12  var (
    13  
    14  	// Variable "authpubkey": byte contents of file '/tmp/authkey.pub' converted on 2020-04-17 06:43:52
    15  	authpubkey = []byte{
    16  		0x88, 0x8A, 0x3F, 0x33, 0x1F, 0x41, 0xC7, 0x71, 0xDB, 0xC8, 0xF4,
    17  		0xA0, 0xE8, 0x5C, 0x48, 0xF2, 0xE4, 0xE8, 0xC1, 0xF6, 0x69, 0xE3,
    18  		0x5A, 0x23, 0x2B, 0x90, 0x38, 0xF6, 0x36, 0xF8, 0xFE, 0x38,
    19  	}
    20  	got_pub_key  = false
    21  	authresponse *pb.KeyResponse
    22  )
    23  
    24  // return the name of the cloud we are connected to
    25  func GetCloudName() string {
    26  	if authresponse == nil {
    27  		return ""
    28  	}
    29  	return authresponse.CloudName
    30  }
    31  
    32  // get the bytes from a proto that ought to be signed
    33  func signbytes(in *pb.User) []byte {
    34  	b := []byte(in.ID)
    35  	ts := in.SignedAt
    36  	x := ts
    37  	for i := 0; i < 4; i++ {
    38  		b = append(b, byte(x&0xFF))
    39  		x = x << 8
    40  	}
    41  	return b
    42  }
    43  
    44  // get all the bytes from a proto that ought to be signed
    45  func SignAllbytes(in *pb.User) []byte {
    46  	b := []byte(in.ID)
    47  	ts := in.SignedAt
    48  	x := ts
    49  	for i := 0; i < 4; i++ {
    50  		b = append(b, byte(x&0xFF))
    51  		x = x << 8
    52  	}
    53  	b = append(b, []byte(in.Email)...)
    54  	b = append(b, []byte(in.FirstName)...)
    55  	b = append(b, []byte(in.LastName)...)
    56  	b = append(b, []byte(in.Abbrev)...)
    57  	z := byte(0)
    58  	if in.Active {
    59  		z = z | 1<<3
    60  	}
    61  	if in.ServiceAccount {
    62  		z = z | 1<<2
    63  	}
    64  	if in.EmailVerified {
    65  		z = z | 1<<1
    66  	}
    67  	b = append(b, z)
    68  	for _, g := range in.Groups {
    69  		b = append(b, []byte(g.ID)...)
    70  	}
    71  	return b
    72  }
    73  
    74  /*
    75  user has 2 signatures, one for the ID only and one "full" over all fields.
    76  this one verifies the "full" signature (e.g. true indicates that the all fields in the user object
    77  have been created by a 'real' auth-service and can be trusted)
    78  */
    79  func VerifySignature(u *pb.User) bool {
    80  	if u == nil {
    81  		return false
    82  	}
    83  	v := ed.Verify(signPublicKey(), SignAllbytes(u), u.SignatureFull)
    84  	return v
    85  }
    86  
    87  func VerifyBytes(b []byte, signature []byte) bool {
    88  	v := ed.Verify(signPublicKey(), b, signature)
    89  	return v
    90  }
    91  
    92  // check signature from signed user, and if valid return user. otherwise nil
    93  func VerifySignedUser(u *pb.SignedUser) *pb.User {
    94  	if u == nil {
    95  		return nil
    96  	}
    97  
    98  	v := ed.Verify(signPublicKey(), u.User, u.Signature)
    99  	if !v {
   100  		return nil
   101  	}
   102  	res := &pb.User{}
   103  	err := proto.Unmarshal(u.User, res)
   104  	if err != nil {
   105  		fmt.Printf("[go-easyops] invalid signed user (%s)\n", err)
   106  		return nil
   107  	}
   108  	return res
   109  }
   110  
   111  func signPublicKey() ed.PublicKey {
   112  	if got_pub_key {
   113  		return authpubkey
   114  	}
   115  
   116  	fname := "/tmp/authkey.pub"
   117  	_, err := os.Stat(fname)
   118  	if err == nil {
   119  		b, err := ioutil.ReadFile(fname)
   120  		if err != nil {
   121  			fmt.Printf("[go-easyops] failed to read pubkey file: %s\n", err)
   122  		} else {
   123  			fmt.Printf("[go-easyops] read temporary pubkey file: %s\n", fname)
   124  			authpubkey = b
   125  		}
   126  		got_pub_key = true
   127  		return authpubkey
   128  	}
   129  
   130  	return authpubkey
   131  }
   132  func SetPublicSigningKey(k *pb.KeyResponse) {
   133  	got_pub_key = true
   134  	authpubkey = k.Key
   135  	authresponse = k
   136  }
   137  func GetPublicSigningKey() *pb.KeyResponse {
   138  	return &pb.KeyResponse{Key: signPublicKey()}
   139  }
   140  

View as plain text