func (alg *AesGcmKW) Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) { if kek, ok := key.([]byte); ok { kekSizeBits := len(kek) << 3 if kekSizeBits != alg.keySizeBits { return nil, errors.New(fmt.Sprintf("AesGcmKW.Unwrap(): expected key of size %v bits, but was given %v bits.", alg.keySizeBits, kekSizeBits)) } var iv, tag string if iv, ok = header["iv"].(string); !ok { return nil, errors.New("AesGcmKW.Unwrap(): expected 'iv' param in JWT header, but was not found.") } if tag, ok = header["tag"].(string); !ok { return nil, errors.New("AesGcmKW.Unwrap(): expected 'tag' param in JWT header, but was not found.") } var ivBytes, tagBytes []byte if ivBytes, err = base64url.Decode(iv); err != nil { return nil, err } if tagBytes, err = base64url.Decode(tag); err != nil { return nil, err } var block cipher.Block if block, err = aes.NewCipher(kek); err != nil { return nil, err } var aesgcm cipher.AEAD if aesgcm, err = cipher.NewGCM(block); err != nil { return nil, err } cipherAndTag := append(encryptedCek, tagBytes...) if cek, err = aesgcm.Open(nil, ivBytes, cipherAndTag, nil); err != nil { fmt.Printf("err = %v\n", err) return nil, err } return cek, nil } return nil, errors.New("AesGcmKW.Unwrap(): expected key to be '[]byte' array") }
func (alg *Pbse2HmacAesKW) Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) { if passphrase, ok := key.(string); ok { var p2s string var p2c float64 if p2c, ok = header["p2c"].(float64); !ok { return nil, errors.New("Pbse2HmacAesKW.Unwrap(): expected 'p2c' param in JWT header, but was not found.") } if p2s, ok = header["p2s"].(string); !ok { return nil, errors.New("Pbse2HmacAesKW.Unwrap(): expected 'p2s' param in JWT header, but was not found.") } var saltInput []byte algId := []byte(header["alg"].(string)) if saltInput, err = base64url.Decode(p2s); err != nil { return nil, err } salt := arrays.Concat(algId, []byte{0}, saltInput) kek := kdf.DerivePBKDF2([]byte(passphrase), salt, int(p2c), alg.keySizeBits, alg.prf()) return alg.aesKW.Unwrap(encryptedCek, kek, cekSizeBits, header) } return nil, errors.New("Pbse2HmacAesKW.Unwrap(): expected key to be 'string' array") }
func (alg *Ecdh) Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) { if privKey, ok := key.(*ecdsa.PrivateKey); ok { var epk map[string]interface{} if epk, ok = header["epk"].(map[string]interface{}); !ok { return nil, errors.New("Ecdh.Unwrap(): expected 'epk' param in JWT header, but was not found.") } if _, ok := header[alg.idHeader()].(string); !ok { return nil, errors.New(fmt.Sprintf("Ecdh.Unwrap(): expected '%v' param in JWT header, but was not found.", alg.idHeader())) } var x, y, crv string var xBytes, yBytes []byte if x, ok = epk["x"].(string); !ok { return nil, errors.New("Ecdh.Unwrap(): expects 'epk' key to contain 'x','y' and 'crv' fields, but 'x' was not found.") } if y, ok = epk["y"].(string); !ok { return nil, errors.New("Ecdh.Unwrap(): expects 'epk' key to contain 'x','y' and 'crv' fields, but 'y' was not found.") } if crv, ok = epk["crv"].(string); !ok { return nil, errors.New("Ecdh.Unwrap(): expects 'epk' key to contain 'x','y' and 'crv' fields, but 'crv' was not found.") } if crv != "P-256" && crv != "P-384" && crv != "P-521" { return nil, errors.New(fmt.Sprintf("Ecdh.Unwrap(): unknown or unsupported curve %v", crv)) } if xBytes, err = base64url.Decode(x); err != nil { return nil, err } if yBytes, err = base64url.Decode(y); err != nil { return nil, err } pubKey := ecc.NewPublic(xBytes, yBytes) return alg.deriveKey(pubKey, privKey, cekSizeBits, header), nil } return nil, errors.New("Ecdh.Unwrap(): expected key to be '*ecdsa.PrivateKey'") }
// Parse splitting & decoding compact serialized json web token, returns slice of byte arrays, each representing part of token func Parse(token string) (result [][]byte, e error) { parts := strings.Split(token, ".") result = make([][]byte, len(parts)) for i, part := range parts { if result[i], e = base64url.Decode(part); e != nil { return nil, e } } return result, nil }
// Parse splitting & decoding compact serialized json web token, returns slice of byte arrays, each representing part of token func Parse(token string) [][]byte { parts := strings.Split(token, ".") result := make([][]byte, len(parts)) var e error for i, part := range parts { if result[i], e = base64url.Decode(part); e != nil { panic(e) } } return result }
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()) }
//test utils func datalenFormat(str string) []byte { bytes, _ := base64url.Decode(str) return prependDatalen(bytes) }