63 lines
1.3 KiB
Go
63 lines
1.3 KiB
Go
|
package api
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"crypto/sha256"
|
||
|
"encoding/binary"
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"io"
|
||
|
"log"
|
||
|
"math/rand"
|
||
|
"net/http"
|
||
|
)
|
||
|
|
||
|
// options are the things that we may need to know about a request to fulfill it properly
|
||
|
type options struct {
|
||
|
KeyType string `json:"kty"`
|
||
|
Seed int64 `json:"-"`
|
||
|
SeedStr string `json:"seed"`
|
||
|
rndReader io.Reader `json:"-"`
|
||
|
}
|
||
|
|
||
|
func getOpts(r *http.Request) (*options, error) {
|
||
|
rndReader := RandomReader
|
||
|
tok := make(map[string]interface{})
|
||
|
decoder := json.NewDecoder(r.Body)
|
||
|
err := decoder.Decode(&tok)
|
||
|
if nil != err && io.EOF != err {
|
||
|
log.Printf("json decode error: %s", err)
|
||
|
return nil, errors.New("Bad Request: invalid json body")
|
||
|
}
|
||
|
defer r.Body.Close()
|
||
|
|
||
|
var seed int64
|
||
|
seedStr, _ := tok["seed"].(string)
|
||
|
if "" != seedStr {
|
||
|
if len(seedStr) > 256 {
|
||
|
return nil, errors.New("Bad Request: base64 seed should be <256 characters (and is truncated to 64-bits anyway)")
|
||
|
}
|
||
|
b := sha256.Sum256([]byte(seedStr))
|
||
|
seed, _ = binary.ReadVarint(bytes.NewReader(b[0:8]))
|
||
|
}
|
||
|
|
||
|
if 0 != seed {
|
||
|
rndReader = rand.New(rand.NewSource(seed))
|
||
|
}
|
||
|
|
||
|
kty, _ := tok["kty"].(string)
|
||
|
if "" == kty {
|
||
|
if 0 == rand.Intn(2) {
|
||
|
kty = "RSA"
|
||
|
} else {
|
||
|
kty = "EC"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return &options{
|
||
|
KeyType: kty,
|
||
|
Seed: seed,
|
||
|
rndReader: rndReader,
|
||
|
}, nil
|
||
|
}
|