// validation_rest.go posts XML content to a remote validation API and prints
// the HTTP response.
//
// Version: 1.0.0 (2026-06-28T06:59Z)
// Author: David Ireland <https://di-mgt.com.au/contact>
// Copyright: 2026 DI Management Services Pty Ltd
// SPDX-License-Identifier: Apache-2.0
// Usage:
//
// go run validation_rest.go
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
)
func read_text_file(fname string) string {
data, err := os.ReadFile(fname)
if err != nil {
panic(err)
}
// Cast bytes to string
content := string(data)
return content
}
// loadCert loads certificate data from either a file path or a certificate string.
// If certfileOrString is empty, it returns an empty string without error.
// If certfileOrString refers to a readable file, the file is loaded and returned
// either as base64-encoded bytes for binary certs or as raw text for PEM/base64 files.
// If certfileOrString is long and does not exist as a file, it is assumed to be
// a literal certificate string.
func loadCert(certfileOrString string) (string, error) {
if certfileOrString == "" {
return "", nil
}
// Not a filename so assume a plain base64 or PEM string
// (we'll catch any errors later)
if len(certfileOrString) > 250 {
if _, err := os.Stat(certfileOrString); os.IsNotExist(err) {
return certfileOrString, nil
}
}
if _, err := os.Stat(certfileOrString); err != nil {
if os.IsNotExist(err) {
return "", fmt.Errorf("file %q not found", certfileOrString)
}
return "", err
}
// Read in the file contents
data, err := os.ReadFile(certfileOrString)
if err != nil {
return "", err
}
if len(data) == 0 {
return "", fmt.Errorf("%q is empty", certfileOrString)
}
// Certificate file could be binary .cer or textual PEM .crt or plain base64
// Examine first byte to guess at form
switch data[0] {
case '0': // binary
return base64.StdEncoding.EncodeToString(data), nil
case 'M', '-': // Base64 or PEM
return string(data), nil
default:
return "", fmt.Errorf("%q is not a valid certificate", certfileOrString)
}
}
// validate posts XML content to the FirmaSAT validation REST API.
// xmlfile is the input XML filename and certfile_or_string is an optional
// PAC certificate file path or certificate string. The function reads the XML,
// optionally loads the certificate, sends the JSON payload, and prints the API
// response with pretty-printed JSON.
func validate(xmlfile string, certfile_or_string string) {
// Local constants
url := "https://di-mgt.com.au/cryptosys/api/fsa_validation"
api_token := "YOUR_API_TOKEN_HERE" // Replace with your own api-token
fmt.Printf("FILE: %s\n", xmlfile)
// 1. Read in the XML content
xmlContent := read_text_file(xmlfile)
// Optional pac-cert file (or string)
certContent := ""
if certfile_or_string != "" {
var err error
certContent, err = loadCert(certfile_or_string)
if err != nil {
log.Fatal(err)
}
}
// 2. Create a JSON payload containing the XML string
payload := map[string]string{
"api-token": api_token,
"xmldata": xmlContent,
"pac-cert": certContent,
}
// 3. Marshal the payload into JSON bytes
jsonData, err := json.Marshal(payload)
if err != nil {
log.Fatal(err)
}
// 4. Create the HTTP POST request
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
log.Fatal(err)
}
req.Header.Set("Content-Type", "application/json")
// 5. Execute the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// Read the response body
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Status: %s\n", resp.Status)
// Pretty-print the JSON response, coping with inner JSON object
var pretty bytes.Buffer
var responseData map[string]interface{}
if err := json.Unmarshal(body, &responseData); err == nil {
if vr, ok := responseData["validation-result"].(string); ok {
var inner interface{}
if err := json.Unmarshal([]byte(vr), &inner); err == nil {
responseData["validation-result"] = inner
}
}
if out, err := json.MarshalIndent(responseData, "", " "); err == nil {
fmt.Printf("Response body:\n%s\n", string(out))
} else {
fmt.Printf("Response body:\n%s\n", pretty.String())
}
} else if err := json.Indent(&pretty, body, "", " "); err == nil {
fmt.Printf("Response body:\n%s\n", pretty.String())
} else {
fmt.Printf("Response body:\n%s\n", string(body))
}
}
func main() {
// These two files must exist in the CWD
validate("cfdv40-ejemplo-signed-tfd.xml", "pac.cer") // binary cert
}