/* $Id: diSc14n.h $ */
/* Copyright (C) 2017-22 DI Management Services Pty Limited.
All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net>
Last updated:
$Date: 2022-04-03 08:23 $
$Revision: 3.1.0 $
*/
/* This source file has markup for Doxygen documentation <http://www.doxygen.org/> */
/**
@file
@brief The C/C++ interface to the <b>diSc14n.dll</b> library.
@par Supported XML Canonicalization Transformations
The following C14N transformations are supported:<br>
<br>
"inclusive canonicalization" from
<a href="http://www.w3.org/TR/2001/REC-xml-c14n-20010315">Canonical XML Version 1.0</a>
(reproduced as <a href="https://tools.ietf.org/html/rfc3076">RFC 3076</a>) with identifiers
<pre>
%http://www.w3.org/TR/2001/REC-xml-c14n-20010315
%http://www.w3.org/TR/2001/REC-xml-c14n-20010315\#WithComments
</pre>
"exclusive canonicalization" from
<a href="http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/">Exclusive XML Canonicalization Version 1.0</a>
(reproduced as <a href="https://tools.ietf.org/html/rfc3741">RFC 3741</a>) with identifiers
<pre>
%http://www.w3.org/2001/10/xml-exc-c14n\#
%http://www.w3.org/2001/10/xml-exc-c14n\#WithComments
</pre>
Identifier | nOptions
------------- | -------------
`http://www.w3.org/TR/2001/REC-xml-c14n-20010315` | `0`
`http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments` | `#SC14N_METHOD_WITHCOMMENTS`
`http://www.w3.org/2001/10/xml-exc-c14n#` | `#SC14N_METHOD_EXCLUSIVE`
`http://www.w3.org/2001/10/xml-exc-c14n#WithComments` | `#SC14N_METHOD_EXCLUSIVE` \| `#SC14N_METHOD_WITHCOMMENTS`
@par Supported XML encodings
Input is expected to be a well-formed XML document.
Supported XML encodings are `UTF-8`, `ISO-8859-1` and `US-ASCII`.
@par Output to szOut buffer
Functions that provide output in `szOut` require the buffer to be pre-dimensioned
(i.e. allocated) to at least the specified length `nOutChars`
PLUS one extra for the null-terminating byte.
These functions always return the total length in bytes of the string they tried to create.
To find the required length, pass a NULL `szOut` or zero `nOutChars` argument,
then add one to the result for the required buffer size.
For example:
@code
char *xmlfile = "test.xml";
long nchars;
char *lpszOut;
// Find out how many bytes we need
nchars = C14N_File2String(NULL, 0, xmlfile, "", 0);
if (nchars <= 0) error();
// Pre-dimension, i.e allocate memory for string buffer
lpszOut = malloc(nchars+1); // NB +1
if (!lpszOut) error();
nchars = C14N_File2String(lpszOut, nchars, xmlfile, "", 0);
// ...
// do something with lpszOut...
// ...
free(lpszOut);
@endcode
@anchor nameorid
@par Specifying the tag name or Id with szNameOrId
Use the `szNameOrId` parameter to specify the element of the XML document to include or omit.
- With options #SC14N_TRAN_OMITBYTAG or #SC14N_TRAN_SUBSETBYTAG, `szNameOrId` specifies the element's tag name.
- By default, the *first* element with a matching tag name will be chosen.
- To specify the N'th element, write as `tagname[N]` where `N=1,2,3,...`
- With options #SC14N_TRAN_OMITBYID or #SC14N_TRAN_SUBSETBYID, `szNameOrId` specifies the element's Id
- The default Id attribute name is `Id`, so the argument `myvalue` will find the element with `Id="myvalue"`.
- To use a different attribute name -- for example `ID` -- write in the form `ID=myvalue` with no quotes.
- With option #SC14N_TRAN_ENTIRE, the parameter is ignored, so just use `""` or `NULL`.
Exactly one element will be omitted or included.
Tag names and Id values are case sensitive.
It is an error (`NO_DATA_ERROR`) if no matching element is found.
@code
// Example 1. Omits the first element with the tag name <Signature>
r = C14N_File2File("c14nfile1.txt", "input.xml", "Signature", "", SC14N_TRAN_OMITBYTAG);
// Example 2. Finds and transforms the first element with the tag name <SignedInfo>
r = C14N_File2File("c14nfile2.txt", "input.xml", "SignedInfo", "", SC14N_TRAN_SUBSETBYTAG);
// Example 3. Finds and transforms the third element with the tag name <Data>
r = C14N_File2File("c14nfile3.txt", "input.xml", "Data[3]", "", SC14N_TRAN_SUBSETBYTAG);
// Example 4. Finds and transforms the element with attribute Id="foo"
r = C14N_File2File("c14nfile4.txt", "input.xml", "foo", "", SC14N_TRAN_SUBSETBYID);
// Example 5. Finds and transforms the element with attribute ID="bar"
r = C14N_File2File("c14nfile5.txt", "input.xml", "ID=bar", "", SC14N_TRAN_SUBSETBYID);
// Example 6. Omits element with attribute Id="thesig"
r = C14N_File2File("c14nfile6.txt", "input.xml", "thesig", "", SC14N_TRAN_OMITBYID);
@endcode
*/
#ifndef DISC14N_H_
#define DISC14N_H_ 1
#include <wchar.h>
/** @cond */
/* __stdcall convention required for Win32 DLL only */
#if __APPLE__
#define __stdcall __attribute__ ((visibility ("default")))
#elif (!( defined(_WIN32) || defined(WIN32) ))
#define __stdcall
#endif
/** @endcond */
/* OPTION FLAGS */
#define SC14N_DIG_DEFAULT 0 /**< Use default digest algorithm (SHA-1) */
#define SC14N_DIG_SHA1 0 /**< Use SHA-1 digest algorithm (default) */
#define SC14N_DIG_SHA256 0x2000 /**< Use SHA-256 digest algorithm */
#define SC14N_DIG_SHA384 0x3000 /**< Use SHA-384 digest algorithm */
#define SC14N_DIG_SHA512 0x5000 /**< Use SHA-512 digest algorithm */
/** Flatten the XML - remove all ignorable whitespace between tags */
#define SC14N_OPT_FLATTEN 0x10000
/* ACTION FLAGS */
/** Transform the entire document (default) */
#define SC14N_TRAN_ENTIRE 0
/** Omit the element with the given tag name */
#define SC14N_TRAN_OMITBYTAG 0x01
/** Transform the subset with the given tag name */
#define SC14N_TRAN_SUBSETBYTAG 0x02
/** Omit the element with the given Id */
#define SC14N_TRAN_OMITBYID 0x11
/** Transform the subset with the given Id */
#define SC14N_TRAN_SUBSETBYID 0x12
/** @cond */
/* DEPRECATED FLAGS (use OMIT instead) */
/** Omit (exclude) the element with the given tag name [<i>deprecated</i>]
@deprecated Use `#SC14N_TRAN_OMITBYTAG`
*/
#define SC14N_TRAN_EXCLUDEBYTAG 0x01
/** Omit (exclude) the element with the given Id [<i>deprecated</i>]
@deprecated Use `#SC14N_TRAN_OMITBYID`
*/
#define SC14N_TRAN_EXCLUDEBYID 0x11
/** @endcond */
/** Use inclusive c14n method [RFC 3076] (default) */
#define SC14N_METHOD_INCLUSIVE 0
/** Use exclusive c14n method [RFC 3741] */
#define SC14N_METHOD_EXCLUSIVE 0x100
/** Include comments in c14n form (@c \#WithComments) */
#define SC14N_METHOD_WITHCOMMENTS 0x800
/* CONSTANTS */
/** Maximum number of characters in base64-encoded hash digest value */
#define SC14N_MAX_DIGEST_CHARS 88
/** Maximum number of characters in an error message */
#define SC14N_MAX_ERROR_CHARS 4073
#ifdef __cplusplus
extern "C" {
#endif
/* GENERAL DIAGNOSTIC FUNCTIONS */
/** Gets version number of the core DLL.
@return Version number as an integer in the form `major*10000+minor*100+revision`
e.g. DLL file version 1.2.x.3 will return 10203 */
long __stdcall SC14N_Gen_Version(void);
/** Gets date and time the core DLL module was last compiled.
@param [out] szOut Buffer to receive output string
@param [in] nOutChars Maximum length of output string in bytes
@return Number of characters in or required for output string;
or a @link SC14N_Err_ErrorLookup() negative error code @endlink. */
long __stdcall SC14N_Gen_CompileTime(char *szOut, long nOutChars);
/** Gets full path name of core DLL module.
@param [out] szOut Buffer to receive output string
@param [in] nOutChars Maximum length of output string in bytes.
@param [in] nOptions Not used. Specify zero.
@return Number of characters in or required for output string;
or a @link SC14N_Err_ErrorLookup() negative error code @endlink */
long __stdcall SC14N_Gen_ModuleName(char *szOut, long nOutChars, long nOptions);
/** Gets platform on which the core DLL is running ("Win32" or "Win64").
@param [out] szOut Buffer to receive output string
@param [in] nOutChars Maximum length of output string in bytes
@return Number of characters in or required for output string;
or a @link SC14N_Err_ErrorLookup() negative error code @endlink. */
long __stdcall SC14N_Gen_Platform(char *szOut, long nOutChars);
/** Gets licence type.
@returns ASCII value of the licence type: 'D'=Developer, 'T'=Trial
@remark Note the Australian/English spelling of "Licence". */
long __stdcall SC14N_Gen_LicenceType(void);
/* ERROR-RELATED FUNCTIONS */
/** Retrieves the last error message (if available).
@param [out] szOut Buffer to receive output string
@param [in] nOutChars Maximum length of output string in bytes. Will not exceed `SC14N_MAX_ERROR_CHARS`.
@return Number of characters in or required for output string;
or a @link SC14N_Err_ErrorLookup() negative error code @endlink.
@remark Call this function to find out more information about the last error.
Not all functions set this.
*/
long __stdcall SC14N_Err_LastError(char *szOut, long nOutChars);
/** Looks up description for error code.
@param [out] szOut Buffer to receive output string
@param [in] nOutChars Maximum length of output string in bytes
@param [in] nErrCode Value of error code to lookup (may be positive or negative)
@return Number of characters in or required for output string;
or a @link SC14N_Err_ErrorLookup() negative error code @endlink. */
long __stdcall SC14N_Err_ErrorLookup(char *szOut, long nOutChars, long nErrCode);
/***********************/
/* MAIN C14N FUNCTIONS */
/***********************/
/** Performs C14N transformation of XML document (file-to-file).
@param [in] szOutputFile Name of output file to create (will be overwritten if exists)
@param [in] szInputFile Name of input file containing XML document to be processed
@param [in] szNameOrId To specify the tag name or Id. See @ref nameorid "Specifying the tag name or Id".
@param [in] szParams InclusiveNamespaces PrefixList parameter (exclusive C14n only). Use `""` or `NULL` to ignore.
@param [in] nOptions Option flags. Select exactly one of:<br>
`#SC14N_TRAN_ENTIRE` (0) to transform the entire document (default)<br>
`#SC14N_TRAN_OMITBYTAG` to omit the element with tag name specified in `szNameOrId`<br>
`#SC14N_TRAN_SUBSETBYTAG` to transform subset with tag name specified in `szNameOrId`<br>
`#SC14N_TRAN_OMITBYID` to omit the element with Id specified in `szNameOrId`<br>
`#SC14N_TRAN_SUBSETBYID` to transform subset with Id specified in `szNameOrId`<br>
and optionally add any of the following. Use the `|` operator to combine:<br>
`#SC14N_METHOD_EXCLUSIVE` to use exclusive c14n method (default is inclusive c14n method)<br>
`#SC14N_METHOD_WITHCOMMENTS` to include comments in c14n form (@c \#WithComments)<br>
`#SC14N_OPT_FLATTEN` to remove all ignorable whitespace between tags<br>
@return Zero (0) on success or a @link SC14N_Err_ErrorLookup() negative error code @endlink.
*/
long __stdcall C14N_File2File(const char *szOutputFile, const char *szInputFile, const char *szNameOrId, const char *szParams, long nOptions);
/** Performs C14N transformation of XML document (file-to-memory).
@param [out] szOut Buffer to receive output as UTF-8 encoded bytes
@param [in] nOutChars Length of output buffer in bytes
@param [in] szInputFile Name of input file containing XML document to be processed
@param [in] szNameOrId To specify the tag name or Id. See @ref nameorid "Specifying the tag name or Id".
@param [in] szParams InclusiveNamespaces PrefixList parameter (exclusive C14n only). Use `""` or `NULL` to ignore.
@param [in] nOptions Option flags. Select exactly one of:<br>
`#SC14N_TRAN_ENTIRE` (0) to transform the entire document (default)<br>
`#SC14N_TRAN_OMITBYTAG` to omit the element with tag name specified in `szNameOrId`<br>
`#SC14N_TRAN_SUBSETBYTAG` to transform subset with tag name specified in `szNameOrId`<br>
`#SC14N_TRAN_OMITBYID` to omit the element with Id specified in `szNameOrId`<br>
`#SC14N_TRAN_SUBSETBYID` to transform subset with Id specified in `szNameOrId`<br>
and optionally add any of the following. Use the `|` operator to combine:<br>
`#SC14N_METHOD_EXCLUSIVE` to use exclusive c14n method (default is inclusive c14n method)<br>
`#SC14N_METHOD_WITHCOMMENTS` to include comments in c14n form (@c \#WithComments)<br>
`#SC14N_OPT_FLATTEN` to remove all ignorable whitespace between tags<br>
@return Number of characters in or required for output string; or a @link SC14N_Err_ErrorLookup() negative error code @endlink.
@remark The output is *always* UTF-8-encoded.
*/
long __stdcall C14N_File2String(char *szOut, long nOutChars, const char *szInputFile, const char *szNameOrId, const char *szParams, long nOptions);
/** Computes digest value of C14N transformation (file-to-digest).
@param [out] szOut Buffer to receive digest value output
@param [in] nOutChars Length of output buffer in bytes
@param [in] szInputFile Name of input file containing XML document to be processed
@param [in] szNameOrId To specify the tag name or Id. See @ref nameorid "Specifying the tag name or Id".
@param [in] szParams InclusiveNamespaces PrefixList parameter (exclusive C14n only). Use `""` or `NULL` to ignore.
@param [in] nOptions Option flags. Select exactly one of:<br>
`#SC14N_TRAN_ENTIRE` (0) to transform the entire document (default)<br>
`#SC14N_TRAN_OMITBYTAG` to omit the element with tag name specified in `szNameOrId`<br>
`#SC14N_TRAN_SUBSETBYTAG` to transform subset with tag name specified in `szNameOrId`<br>
`#SC14N_TRAN_OMITBYID` to omit the element with Id specified in `szNameOrId`<br>
`#SC14N_TRAN_SUBSETBYID` to transform subset with Id specified in `szNameOrId`<br>
and add one of:<br>
`#SC14N_DIG_SHA1` (0) to use SHA-1 algorithm (default) or<br>
`#SC14N_DIG_SHA256` to use SHA-256.<br>
and optionally add any of the following. Use the `|` operator to combine:<br>
`#SC14N_METHOD_EXCLUSIVE` to use exclusive c14n method (default is inclusive c14n method)<br>
`#SC14N_METHOD_WITHCOMMENTS` to include comments in c14n form (@c \#WithComments)<br>
`#SC14N_OPT_FLATTEN` to remove all ignorable whitespace between tags<br>
@return Number of characters in or required for output string; or a @link SC14N_Err_ErrorLookup() negative error code @endlink.
@remark The output is always encoded in base64. The maximum length is `SC14N_MAX_HASH_CHARS`.
*/
long __stdcall C14N_File2Digest(char *szOut, long nOutChars, const char *szInputFile, const char *szNameOrId, const char *szParams, long nOptions);
/** Performs C14N transformation of XML document (memory-to-memory).
@param [out] szOut Buffer to receive output as UTF-8 encoded bytes
@param [in] nOutChars Length of output buffer in bytes
@param [in] lpDataIn Pointer to XML data to be processed
@param [in] nDataLen Length of input data in bytes
@param [in] szNameOrId To specify the tag name or Id. See @ref nameorid "Specifying the tag name or Id".
@param [in] szParams InclusiveNamespaces PrefixList parameter (exclusive C14n only). Use `""` or `NULL` to ignore.
@param [in] nOptions Option flags. Select exactly one of:<br>
`#SC14N_TRAN_ENTIRE` (0) to transform the entire document (default)<br>
`#SC14N_TRAN_OMITBYTAG` to omit the element with tag name specified in `szNameOrId`<br>
`#SC14N_TRAN_SUBSETBYTAG` to transform subset with tag name specified in `szNameOrId`<br>
`#SC14N_TRAN_OMITBYID` to omit the element with Id specified in `szNameOrId`<br>
`#SC14N_TRAN_SUBSETBYID` to transform subset with Id specified in `szNameOrId`<br>
and optionally add any of the following. Use the `|` operator to combine:<br>
`#SC14N_METHOD_EXCLUSIVE` to use exclusive c14n method (default is inclusive c14n method)<br>
`#SC14N_METHOD_WITHCOMMENTS` to include comments in c14n form (@c \#WithComments)<br>
`#SC14N_OPT_FLATTEN` to remove all ignorable whitespace between tags<br>
@return Zero (0) on success or a @link SC14N_Err_ErrorLookup() negative error code @endlink.
@remark The output is *always* UTF-8-encoded.
*/
long __stdcall C14N_String2String(char *szOut, long nOutChars, const void *lpDataIn, long nDataLen, const char *szNameOrId, const char *szParams, long nOptions);
/** Computes digest value of C14N transformation (memory-to-digest).
@param [out] szOut Buffer to receive digest value output
@param [in] nOutChars Length of output buffer in bytes
@param [in] lpDataIn Pointer to XML data to be processed
@param [in] nDataLen Length of input data in bytes
@param [in] szNameOrId To specify the tag name or Id. See @ref nameorid "Specifying the tag name or Id".
@param [in] szParams InclusiveNamespaces PrefixList parameter (exclusive C14n only). Use `""` or `NULL` to ignore.
@param [in] nOptions Option flags. Select exactly one of:<br>
`#SC14N_TRAN_ENTIRE` (0) to transform the entire document (default)<br>
`#SC14N_TRAN_OMITBYTAG` to omit the element with tag name specified in `szNameOrId`<br>
`#SC14N_TRAN_SUBSETBYTAG` to transform subset with tag name specified in `szNameOrId`<br>
`#SC14N_TRAN_OMITBYID` to omit the element with Id specified in `szNameOrId`<br>
`#SC14N_TRAN_SUBSETBYID` to transform subset with Id specified in `szNameOrId`<br>
and add one of:<br>
`#SC14N_DIG_SHA1` (0) to use SHA-1 algorithm (default) or<br>
`#SC14N_DIG_SHA256` to use SHA-256.<br>
and optionally add any of the following. Use the `|` operator to combine:<br>
`#SC14N_METHOD_EXCLUSIVE` to use exclusive c14n method (default is inclusive c14n method)<br>
`#SC14N_METHOD_WITHCOMMENTS` to include comments in c14n form (@c \#WithComments)<br>
`#SC14N_OPT_FLATTEN` to remove all ignorable whitespace between tags<br>
@return Number of characters in or required for output string; or a @link SC14N_Err_ErrorLookup() negative error code @endlink.
@remark The output is always encoded in base64. The maximum length is `SC14N_MAX_HASH_CHARS`.
*/
long __stdcall C14N_String2Digest(char *szOut, long nOutChars, const void *lpDataIn, long nDataLen, const char *szNameOrId, const char *szParams, long nOptions);
/*******************************/
/* UTILITY CONVERSION FUNCTION */
/*******************************/
/** Maps a UTF-16 (wide character) string to a UTF-8-encoded string.
@param [out] szOut Buffer to receive null-terminated UTF-8-encoded string.
@param [in] nOutChars Maximum length of output string in bytes (excluding the terminating null).
@param [in] wstr String of wide characters to be processed.
@return Number of characters (bytes) in or required for the output string; or a @link SC14N_Err_ErrorLookup() negative error code @endlink.
@remark Pass a NULL `szOut` or zero `nOutChars` to find the required output length in bytes. Allocate one extra byte for the terminating null.
@remark
```
long nchars;
char *buf = NULL;
wchar_t *wstr = L"áéíñóü"
// Find required output length (12 in this case)
nchars = SC14N_Utf8FromWide(NULL, 0, wstr);
printf("SC14N_Utf8FromWide returns %ld\n", nchars);
assert(nchars >= 0);
buf = malloc(nchars + 1); // NB one extra byte
nchars = SC14N_Utf8FromWide(buf, nchars, wstr);
assert(nchars >= 0);
// Assumes console codepage is set to UTF-8
printf("[%s]\n", buf);
free(buf);
```
*/
long __stdcall SC14N_Utf8FromWide(char *szOut, long nOutChars, const wchar_t* wstr);
#ifdef __cplusplus
}
#endif
#endif /* DISC14N_H_ */