package dns

import (
	
	
	
	
	
	
	
)

// Generate generates a DNSKEY of the given bit size.
// The public part is put inside the DNSKEY record.
// The Algorithm in the key must be set as this will define
// what kind of DNSKEY will be generated.
// The ECDSA algorithms imply a fixed keysize, in that case
// bits should be set to the size of the algorithm.
func ( *DNSKEY) ( int) (crypto.PrivateKey, error) {
	switch .Algorithm {
	case RSASHA1, RSASHA256, RSASHA1NSEC3SHA1:
		if  < 512 ||  > 4096 {
			return nil, ErrKeySize
		}
	case RSASHA512:
		if  < 1024 ||  > 4096 {
			return nil, ErrKeySize
		}
	case ECDSAP256SHA256:
		if  != 256 {
			return nil, ErrKeySize
		}
	case ECDSAP384SHA384:
		if  != 384 {
			return nil, ErrKeySize
		}
	case ED25519:
		if  != 256 {
			return nil, ErrKeySize
		}
	default:
		return nil, ErrAlg
	}

	switch .Algorithm {
	case RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1:
		,  := rsa.GenerateKey(rand.Reader, )
		if  != nil {
			return nil, 
		}
		.setPublicKeyRSA(.PublicKey.E, .PublicKey.N)
		return , nil
	case ECDSAP256SHA256, ECDSAP384SHA384:
		var  elliptic.Curve
		switch .Algorithm {
		case ECDSAP256SHA256:
			 = elliptic.P256()
		case ECDSAP384SHA384:
			 = elliptic.P384()
		}
		,  := ecdsa.GenerateKey(, rand.Reader)
		if  != nil {
			return nil, 
		}
		.setPublicKeyECDSA(.PublicKey.X, .PublicKey.Y)
		return , nil
	case ED25519:
		, ,  := ed25519.GenerateKey(rand.Reader)
		if  != nil {
			return nil, 
		}
		.setPublicKeyED25519()
		return , nil
	default:
		return nil, ErrAlg
	}
}

// Set the public key (the value E and N)
func ( *DNSKEY) ( int,  *big.Int) bool {
	if  == 0 ||  == nil {
		return false
	}
	 := exponentToBuf()
	 = append(, .Bytes()...)
	.PublicKey = toBase64()
	return true
}

// Set the public key for Elliptic Curves
func ( *DNSKEY) (,  *big.Int) bool {
	if  == nil ||  == nil {
		return false
	}
	var  int
	switch .Algorithm {
	case ECDSAP256SHA256:
		 = 32
	case ECDSAP384SHA384:
		 = 48
	}
	.PublicKey = toBase64(curveToBuf(, , ))
	return true
}

// Set the public key for Ed25519
func ( *DNSKEY) ( ed25519.PublicKey) bool {
	if  == nil {
		return false
	}
	.PublicKey = toBase64()
	return true
}

// Set the public key (the values E and N) for RSA
// RFC 3110: Section 2. RSA Public KEY Resource Records
func exponentToBuf( int) []byte {
	var  []byte
	 := big.NewInt(int64()).Bytes()
	if len() < 256 {
		 = make([]byte, 1, 1+len())
		[0] = uint8(len())
	} else {
		 = make([]byte, 3, 3+len())
		[0] = 0
		[1] = uint8(len() >> 8)
		[2] = uint8(len())
	}
	 = append(, ...)
	return 
}

// Set the public key for X and Y for Curve. The two
// values are just concatenated.
func curveToBuf(,  *big.Int,  int) []byte {
	 := intToBytes(, )
	 = append(, intToBytes(, )...)
	return 
}