Beispiel #1
0
// Construct takes the node and creates a new Key. The node must be
// a KeyInfo node
func Construct(n types.Node) (Key, error) {
	ne, ok := n.(types.Element)
	if !ok || ne.LocalName() != "KeyInfo" {
		return nil, errors.New("invalid node (expected KeyInfo)")
	}

	kv, err := ne.FirstChild()
	if err != nil {
		return nil, err
	}
	kve, ok := kv.(types.Element)
	if !ok || kve.LocalName() != "KeyValue" {
		return nil, errors.New("invalid node (expected KeyValue)")
	}

	kn, err := kv.FirstChild()
	if err != nil {
		return nil, err
	}
	kne, ok := kn.(types.Element)
	if !ok {
		return nil, errors.New("invalid node (expected element node)")
	}

	switch kne.LocalName() {
	case "RSAKeyValue":
		pubkey := &rsa.PublicKey{}
		children, err := kne.ChildNodes()
		if err != nil {
			return nil, err
		}

		for _, x := range children {
			n, ok := x.(types.Element)
			if !ok {
				return nil, errors.New("invalid under RSAKeyValue")
			}
			switch n.LocalName() {
			case "Modulus":
				v, err := base64.StdEncoding.DecodeString(n.TextContent())
				if err != nil {
					return nil, err
				}
				pubkey.N = (&big.Int{}).SetBytes(v)
			case "Exponent":
				v, err := base64.StdEncoding.DecodeString(n.TextContent())
				if err != nil {
					return nil, err
				}
				if len(v) < 64 {
					b := make([]byte, 64)
					copy(b[64-len(v):], v)
					v = b
				}
				pubkey.E = int(binary.BigEndian.Uint64(v))
			}
		}
		return NewRSA(pubkey), nil
	case "DSAKeyValue":
		pubkey := &dsa.PublicKey{}
		children, err := kne.ChildNodes()
		if err != nil {
			return nil, err
		}

		for _, x := range children {
			n, ok := x.(types.Element)
			if !ok {
				return nil, errors.New("invalid under DSAKeyValue")
			}
			switch n.LocalName() {
			case "P":
				v, err := base64.StdEncoding.DecodeString(n.TextContent())
				if err != nil {
					return nil, err
				}
				pubkey.P = (&big.Int{}).SetBytes(v)
			case "Q":
				v, err := base64.StdEncoding.DecodeString(n.TextContent())
				if err != nil {
					return nil, err
				}
				pubkey.Q = (&big.Int{}).SetBytes(v)
			case "G":
				v, err := base64.StdEncoding.DecodeString(n.TextContent())
				if err != nil {
					return nil, err
				}
				pubkey.G = (&big.Int{}).SetBytes(v)
			case "Y":
				v, err := base64.StdEncoding.DecodeString(n.TextContent())
				if err != nil {
					return nil, err
				}
				pubkey.Y = (&big.Int{}).SetBytes(v)
			}
		}
		return NewDSA(pubkey), nil
	default:
		return nil, errors.New("invalid node expected: DSAKeyValue or RSAKeyValue")
	}
}