Example #1
0
// Sign the given context with the given private key - which is a PEM or hsm: key
// A hsm: key is a urn 'key' that points to a specific key/action in a goeleven interface to a HSM
// See https://github.com/wayf-dk/goeleven
func (xp *Xp) Sign(context *C.xmlNode, privatekey, pw, cert, algo string) (err error) {
	contextHash := Hash(algos[algo].algo, xp.C14n(context))
	contextDigest := base64.StdEncoding.EncodeToString(contextHash)
	signaturexml := `<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
  <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
  <ds:SignatureMethod Algorithm=""/>
  <ds:Reference URI="">
    <ds:Transforms>
      <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
      <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    </ds:Transforms>
    <ds:DigestMethod Algorithm=""/>
    <ds:DigestValue></ds:DigestValue>
  </ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue></ds:SignatureValue>
</ds:Signature>`

	signature := C.xmlNewDocFragment(xp.doc)
	var res C.xmlNodePtr
	buf := ([]byte)(signaturexml)
	C.xmlParseBalancedChunkMemory(xp.doc, nil, nil, 0, (*C.xmlChar)(&buf[0]), &res)
	C.xmlAddChildList(signature, res)
	C.xmlAddNextSibling(C.xmlFirstElementChild(context), signature)

	id := xp.Query1(context, "@ID")

	signedInfo := xp.QueryDashP(signature, `ds:Signature/ds:SignedInfo[1]`, "", nil)
	xp.QueryDashP(signedInfo, `ds:SignatureMethod[1]/@Algorithm`, algos[algo].signature, nil)
	xp.QueryDashP(signedInfo, `ds:Reference/@URI`, "#"+id, nil)
	xp.QueryDashP(signedInfo, `ds:Reference/ds:DigestMethod[1]/@Algorithm`, algos[algo].digest, nil)
	xp.QueryDashP(signedInfo, `ds:Reference/ds:DigestValue[1]`, contextDigest, nil)

	signedInfoC14n := xp.C14n(signedInfo)
	digest := Hash(algos[algo].algo, signedInfoC14n)

	var signaturevalue []byte
	if strings.HasPrefix(privatekey, "hsm:") {
		signaturevalue, err = signGoEleven(digest, privatekey, algo)
	} else {
		signaturevalue, err = signGo(digest, privatekey, pw, algo)
	}
	signatureval := base64.StdEncoding.EncodeToString(signaturevalue)
	xp.QueryDashP(signature, `ds:Signature/ds:SignatureValue`, signatureval, nil)
	xp.QueryDashP(signature, `ds:Signature/ds:KeyInfo/ds:X509Data/ds:X509Certificate`, cert, nil)
	//	log.Println(xp.Pp())
	return
}
Example #2
0
// Decrypt decrypts the context using the given privatekey
func (xp *Xp) Decrypt(context *C.xmlNode, privatekey *rsa.PrivateKey) (decryptedAssertion *C.xmlNode) {
	// for now just use what we send ourselves ...
	encryptedkey := xp.Query1(context, "./xenc:EncryptedData/ds:KeyInfo/xenc:EncryptedKey/xenc:CipherData/xenc:CipherValue")
	encryptedkeybyte, _ := base64.StdEncoding.DecodeString(encryptedkey)
	sessionkey, _ := rsa.DecryptOAEP(sha1.New(), rand.Reader, privatekey, encryptedkeybyte, nil)
	encryptedassertion := xp.Query1(context, "./xenc:EncryptedData/xenc:CipherData/xenc:CipherValue")
	encryptedassertionbyte, _ := base64.StdEncoding.DecodeString(encryptedassertion)
	assertion := decryptAES([]byte(sessionkey), encryptedassertionbyte)
	assertion = append(assertion, 0)

	var res C.xmlNodePtr
	decryptedAssertion = C.xmlNewDocFragment(xp.doc)
	C.xmlParseBalancedChunkMemory(xp.doc, nil, nil, 0, (*C.xmlChar)(&assertion[0]), &res)
	C.xmlAddChildList(decryptedAssertion, res)
	C.xmlReplaceNode(context, decryptedAssertion)
	C.xmlReconciliateNs(xp.doc, decryptedAssertion)

	return
}
Example #3
0
// Encrypt the context with the given publickey
// Hardcoded to aes256-cbc for the symetric part and
// rsa-oaep-mgf1p and sha1 for the rsa part
func (xp *Xp) Encrypt(context *C.xmlNode, publickey *rsa.PublicKey) {
	template := []byte(`<saml:EncryptedAssertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
    <xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element">
        <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
        <ds:KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <xenc:EncryptedKey >
                <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
                    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                </xenc:EncryptionMethod>
                <xenc:CipherData>
                    <xenc:CipherValue>encryptedsessionkey</xenc:CipherValue>
                </xenc:CipherData>
            </xenc:EncryptedKey>
        </ds:KeyInfo>
        <xenc:CipherData>
            <xenc:CipherValue>encryptedassertion</xenc:CipherValue>
        </xenc:CipherData>
    </xenc:EncryptedData>
</saml:EncryptedAssertion>`)

	var res C.xmlNodePtr
	encryptedAssertion := C.xmlNewDocFragment(xp.doc)
	C.xmlParseBalancedChunkMemory(xp.doc, nil, nil, 0, (*C.xmlChar)(&template[0]), &res)
	C.xmlAddChildList(encryptedAssertion, res)

	//sessionkey, ciphertext := encryptAES([]byte(xp.C14n(context)))
	sessionkey, ciphertext := encryptAES([]byte(xp.Dump2(context)))
	sessionkey, err := rsa.EncryptOAEP(sha1.New(), rand.Reader, publickey, sessionkey, nil)
	if err != nil {
		panic(err)
	}

	ec := xp.QueryDashP(encryptedAssertion, `saml:EncryptedAssertion/xenc:EncryptedData`, "", nil)
	xp.QueryDashP(ec, `ds:KeyInfo/xenc:EncryptedKey/xenc:CipherData/xenc:CipherValue`, base64.StdEncoding.EncodeToString(sessionkey), nil)
	xp.QueryDashP(ec, `xenc:CipherData/xenc:CipherValue`, base64.StdEncoding.EncodeToString(ciphertext), nil)
	C.xmlReplaceNode(context, encryptedAssertion)
}