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'") }
// Dump produces printable debug representation of byte array as string func Dump(arr []byte) string { var buf bytes.Buffer buf.WriteString("(") buf.WriteString(fmt.Sprintf("%v", len(arr))) buf.WriteString(" bytes)[") for idx, b := range arr { buf.WriteString(fmt.Sprintf("%v", b)) if idx != len(arr)-1 { buf.WriteString(", ") } } buf.WriteString("], Hex: [") for idx, b := range arr { buf.WriteString(fmt.Sprintf("%X", b)) if idx != len(arr)-1 { buf.WriteString(" ") } } buf.WriteString("], Base64Url:") buf.WriteString(base64url.Encode(arr)) return buf.String() }
// Serialize converts given parts into compact serialization format func Serialize(parts ...[]byte) string { result := make([]string, len(parts)) for i, part := range parts { result[i] = base64url.Encode(part) } return strings.Join(result, ".") }
func (alg *AesGcmKW) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) { if kek, ok := key.([]byte); ok { kekSizeBits := len(kek) << 3 if kekSizeBits != alg.keySizeBits { return nil, nil, errors.New(fmt.Sprintf("AesGcmKW.WrapNewKey(): expected key of size %v bits, but was given %v bits.", alg.keySizeBits, kekSizeBits)) } if cek, err = arrays.Random(cekSizeBits >> 3); err != nil { return nil, nil, err } var iv []byte if iv, err = arrays.Random(12); err != nil { return nil, nil, err } var block cipher.Block if block, err = aes.NewCipher(kek); err != nil { return nil, nil, err } var aesgcm cipher.AEAD if aesgcm, err = cipher.NewGCM(block); err != nil { return nil, nil, err } cipherWithTag := aesgcm.Seal(nil, iv, cek, nil) cipherText := cipherWithTag[:len(cipherWithTag)-aesgcm.Overhead()] authTag := cipherWithTag[len(cipherWithTag)-aesgcm.Overhead():] header["iv"] = base64url.Encode(iv) header["tag"] = base64url.Encode(authTag) return cek, cipherText, nil } return nil, nil, errors.New("AesGcmKW.WrapNewKey(): expected key to be '[]byte' array") }
func (alg *Pbse2HmacAesKW) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) { if passphrase, ok := key.(string); ok { algId := []byte(header["alg"].(string)) iterationCount := 8192 var saltInput []byte if saltInput, err = arrays.Random(12); err != nil { return nil, nil, err } header["p2c"] = iterationCount header["p2s"] = base64url.Encode(saltInput) salt := arrays.Concat(algId, []byte{0}, saltInput) kek := kdf.DerivePBKDF2([]byte(passphrase), salt, iterationCount, alg.keySizeBits, alg.prf()) return alg.aesKW.WrapNewKey(cekSizeBits, kek, header) } return nil, nil, errors.New("Pbse2HmacAesKW.WrapNewKey(): expected key to be 'string' array") }