After spending couple of hours, I managed to fix my problem I post my finding so it may save someone's time:
First I reviewed my pem file encoding using this great online tool: http://lapo.it/asn1js/. Only then I realized go is expecting the pem file to have different structure... Not nice! Aftwerwards, it was not hard to relate each value within the file to the corresponding dsa.PrivateKey struct. So, I made a new struct and named it MyPrivateKey with the same order as the pem file:
type MyPrivateKey struct {
E1, P, Q, G, Y, X *big.Int
}
Then, instead of trying to unmarshal directly to dsa.PrivateKey, I unmarshaled the asn1 encoded value to my self made struct. And magically it worked. Here is the modified func:
func getDSAPrivateKeyFromPemFile(pemFilePath string) (privateKey *dsa.PrivateKey, err error) {
pemfile, err := os.Open(pemFilePath)
if err != nil {
return nil, err
}
recoveredBytes, err := ioutil.ReadAll(pemfile)
if err != nil {
return nil, err
}
pemfile.Close()
pemDSAParameters, rest := pem.Decode(recoveredBytes)
if pemDSAParameters == nil {
return nil, errors.New("No pem recovered")
}
pemDSAPrivateKey, _ := pem.Decode(rest)
keyParameters := dsa.Parameters{G: big.NewInt(0), P: big.NewInt(0), Q: big.NewInt(0)}
_, err = asn1.Unmarshal(pemDSAParameters.Bytes, &keyParameters)
if err != nil {
return nil, err
}
//fmt.Printf("
P:%x
G:%x
Q:%x
", keyParameters.P, keyParameters.G, keyParameters.Q)
myPrivateKey := MyPrivateKey{}
_, err = asn1.Unmarshal(pemDSAPrivateKey.Bytes, &myPrivateKey)
if err != nil {
return nil, err
}
//fmt.Printf("
private
E1:%x
P:%x
Q:%x
G:%x
Y:%x
X:%x
", myPrivateKey.E1, myPrivateKey.P, myPrivateKey.Q, myPrivateKey.G, myPrivateKey.Y, myPrivateKey.X)
privateKey = &dsa.PrivateKey{}
privateKey.Parameters = keyParameters
privateKey.X = myPrivateKey.X
return privateKey, nil
}
Maybe there was a much easier way to this all and I simply overlooked! If you know a better way please be my guest! Otherwise, I believe go should handle this kind of issues in the standard libraries.