func (alg *Ecdh) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) { if pubKey, ok := key.(*ecdsa.PublicKey); ok { if _, ok := header[alg.idHeader()].(string); !ok { return nil, nil, errors.New(fmt.Sprintf("Ecdh.WrapNewKey(): expected '%v' param in JWT header, but was not found.", alg.idHeader())) } var d []byte var x, y *big.Int if d, x, y, err = elliptic.GenerateKey(pubKey.Curve, rand.Reader); err != nil { return nil, nil, err } ephemeral := ecc.NewPrivate(x.Bytes(), y.Bytes(), d) xBytes := padding.Align(x.Bytes(), pubKey.Curve.Params().BitSize) yBytes := padding.Align(y.Bytes(), pubKey.Curve.Params().BitSize) epk := map[string]string{ "kty": "EC", "x": base64url.Encode(xBytes), "y": base64url.Encode(yBytes), "crv": name(pubKey.Curve), } header["epk"] = epk return alg.deriveKey(pubKey, ephemeral, cekSizeBits, header), nil, nil } return nil, nil, errors.New("Ecdh.WrapNewKey(): expected key to be '*ecdsa.PublicKey'") }
func (alg *EcdsaUsingSha) Sign(securedInput []byte, key interface{}) (signature []byte, err error) { if privKey, ok := key.(*ecdsa.PrivateKey); ok { if sizeBits := privKey.Curve.Params().BitSize; sizeBits != alg.keySizeBits { return nil, errors.New(fmt.Sprintf("EcdsaUsingSha.Sign(): expected key of size %v bits, but was given %v bits.", alg.keySizeBits, sizeBits)) } var r, s *big.Int if r, s, err = ecdsa.Sign(rand.Reader, privKey, sha(alg.hashSizeBits, securedInput)); err == nil { rBytes := padding.Align(r.Bytes(), alg.keySizeBits) sBytes := padding.Align(s.Bytes(), alg.keySizeBits) return arrays.Concat(rBytes, sBytes), nil } return nil, err } return nil, errors.New("EcdsaUsingSha.Sign(): expects key to be '*ecdsa.PrivateKey'") }
func (alg *Ecdh) deriveKey(pubKey *ecdsa.PublicKey, privKey *ecdsa.PrivateKey, keySizeBits int, header map[string]interface{}) []byte { var enc, apv, apu []byte var err error enc = []byte(header[alg.idHeader()].(string)) if a, ok := header["apv"].(string); !ok { if apv, err = base64url.Decode(a); err != nil { apv = nil } } if a, ok := header["apu"].(string); !ok { if apu, err = base64url.Decode(a); err != nil { apu = nil } } z, _ := pubKey.Curve.ScalarMult(pubKey.X, pubKey.Y, privKey.D.Bytes()) zBytes := padding.Align(z.Bytes(), privKey.Curve.Params().BitSize) return kdf.DeriveConcatKDF(keySizeBits, zBytes, prependDatalen(enc), prependDatalen(apu), prependDatalen(apv), arrays.UInt32ToBytes(uint32(keySizeBits)), nil, sha256.New()) }