include "asn1.s7i";
include "pkcs1.s7i";
include "elliptic.s7i";
include "msgdigest.s7i";
include "unicode.s7i";
include "time.s7i";
include "duration.s7i";
const type: algorithmIdentifierType is new struct
var string: algorithm is "";
var string: subAlgorithm is "";
var string: parameters is "";
end struct;
const type: x509Name is hash [string] string;
const type: x509Validity is new struct
var time: notBefore is time.value;
var time: notAfter is time.value;
end struct;
const type: subjectPublicKeyInfoType is new struct
var algorithmIdentifierType: algorithm is algorithmIdentifierType.value;
var string: subjectPublicKey is "";
var rsaKey: publicRsaKey is rsaKey.value;
var ellipticCurve: eCurve is ellipticCurve.value;
var ecPoint: publicEccKey is ecPoint.value;
end struct;
const type: x509Extension is new struct
var string: extensionOid is "";
var boolean: isCritical is FALSE;
var string: octetStringData is "";
end struct;
const type: tbsCertificateType is new struct
var integer: version is 0;
var string: serialNumber is "";
var algorithmIdentifierType: signature is algorithmIdentifierType.value;
var x509Name: issuer is x509Name.value;
var x509Validity: validity is x509Validity.value;
var x509Name: subject is x509Name.value;
var subjectPublicKeyInfoType: subjectPublicKeyInfo is subjectPublicKeyInfoType.value;
var array x509Extension: extensions is 0 times x509Extension.value;
var integer: digestStartPos is 0;
var integer: digestEndPos is 0;
end struct;
const type: x509Cert is new struct
var tbsCertificateType: tbsCertificate is tbsCertificateType.value;
var algorithmIdentifierType: signatureAlgorithm is algorithmIdentifierType.value;
var string: signatureValue is "";
var string: messageDigest is "";
end struct;
const type: x509cert is x509Cert;
const type: certSubjectIndexHashType is hash [string] integer;
const type: certAndKey is new struct
var array string: certList is 0 times "";
var rsaKey: privateRsaKey is rsaKey.value;
var bigInteger: privateEccKey is 0_;
end struct;
const type: rsaSignatureType is new struct
var algorithmIdentifierType: algorithmIdentifier is algorithmIdentifierType.value;
var string: signature is "";
end struct;
const string: ALIASED_ENTRY_NAME_OID is encodeObjectIdentifier([] (2, 5, 4, 1));
const string: KNOWLEDGE_INFORMATION_OID is encodeObjectIdentifier([] (2, 5, 4, 2));
const string: COMMON_NAME_OID is encodeObjectIdentifier([] (2, 5, 4, 3));
const string: SURNAME_OID is encodeObjectIdentifier([] (2, 5, 4, 4));
const string: SERIAL_NUMBER_OID is encodeObjectIdentifier([] (2, 5, 4, 5));
const string: COUNTRY_NAME_OID is encodeObjectIdentifier([] (2, 5, 4, 6));
const string: LOCALITY_NAME_OID is encodeObjectIdentifier([] (2, 5, 4, 7));
const string: STATE_OR_OR_PROVINCE_NAME_OID is encodeObjectIdentifier([] (2, 5, 4, 8));
const string: STREET_ADDRESS_OID is encodeObjectIdentifier([] (2, 5, 4, 9));
const string: ORGANIZATION_NAME_OID is encodeObjectIdentifier([] (2, 5, 4, 10));
const string: ORGANIZATION_UNIT_NAME_OID is encodeObjectIdentifier([] (2, 5, 4, 11));
const string: TITLE_OID is encodeObjectIdentifier([] (2, 5, 4, 12));
const string: SUBJECT_KEY_IDENTIFIER_OID is encodeObjectIdentifier([] (2, 5, 29, 14));
const string: KEY_USAGE_OID is encodeObjectIdentifier([] (2, 5, 29, 15));
const string: SUBJECT_ALT_NAME is encodeObjectIdentifier([] (2, 5, 29, 17));
const string: BASIC_CONSTRAINTS_OID is encodeObjectIdentifier([] (2, 5, 29, 19));
const string: CRLD_DISTRIBUTION_POINTS_OID is encodeObjectIdentifier([] (2, 5, 29, 31));
const string: CERTIFICATE_POLICIES_OID is encodeObjectIdentifier([] (2, 5, 29, 32));
const string: AUTHORITY_KEY_IDENTIFIER_OID is encodeObjectIdentifier([] (2, 5, 29, 35));
const string: EXT_KEY_USAGE_OID is encodeObjectIdentifier([] (2, 5, 29, 37));
const string: CERT_TYPE_OID is encodeObjectIdentifier([] (2, 16, 840, 1, 113730, 1, 1));
const string: PKCS_1 is encodeObjectIdentifier([] (1, 2, 840, 113549, 1, 1));
const string: RSA_ENCRYPTION_OID is PKCS_1 & "\1;";
const string: MD2_WITH_RSA_ENCRYPTION is PKCS_1 & "\2;";
const string: MD5_WITH_RSA_ENCRYPTION is PKCS_1 & "\4;";
const string: SHA1_WITH_RSA_ENCRYPTION is PKCS_1 & "\5;";
const string: RSAES_OAEP_OID is PKCS_1 & "\7;";
const string: MGF1_OID is PKCS_1 & "\8;";
const string: P_SPECIFIED_OID is PKCS_1 & "\9;";
const string: RSASSA_PSS_OID is PKCS_1 & "\10;";
const string: SHA256_WITH_RSA_ENCRYPTION is PKCS_1 & "\11;";
const string: SHA384_WITH_RSA_ENCRYPTION is PKCS_1 & "\12;";
const string: SHA512_WITH_RSA_ENCRYPTION is PKCS_1 & "\13;";
const string: PKCS_7 is encodeObjectIdentifier([] (1, 2, 840, 113549, 1, 7));
const string: PKCS_7_DATA is PKCS_7 & "\1;";
const string: PKCS_7_SIGNED_DATA is PKCS_7 & "\2;";
const string: PKCS_7_ENVELOPED_DATA is PKCS_7 & "\3;";
const string: PKCS_7_SIGNED_AND_ENVELOPED_DATA is PKCS_7 & "\4;";
const string: PKCS_7_DIGESTED_DATA is PKCS_7 & "\5;";
const string: PKCS_7_ENCRYPTED_DATA is PKCS_7 & "\6;";
const string: ECDSA_WITH_SHA224 is encodeObjectIdentifier([] (1, 2, 840, 10045, 4, 3, 1));
const string: ECDSA_WITH_SHA256 is encodeObjectIdentifier([] (1, 2, 840, 10045, 4, 3, 2));
const string: ECDSA_WITH_SHA384 is encodeObjectIdentifier([] (1, 2, 840, 10045, 4, 3, 3));
const string: ECDSA_WITH_SHA512 is encodeObjectIdentifier([] (1, 2, 840, 10045, 4, 3, 4));
const string: PRIME_FIELD is encodeObjectIdentifier([] (1, 2, 840, 10045, 1, 1));
const string: EC_PUBLIC_KEY is encodeObjectIdentifier([] (1, 2, 840, 10045, 2, 1));
const string: SECP192K1_OID is encodeObjectIdentifier([] (1, 3, 132, 0, 31));
const string: SECP192R1_OID is encodeObjectIdentifier([] (1, 2, 840, 10045, 3, 1, 1));
const string: SECP224K1_OID is encodeObjectIdentifier([] (1, 3, 132, 0, 32));
const string: SECP224R1_OID is encodeObjectIdentifier([] (1, 3, 132, 0, 33));
const string: SECP256K1_OID is encodeObjectIdentifier([] (1, 3, 132, 0, 10));
const string: SECP256R1_OID is encodeObjectIdentifier([] (1, 2, 840, 10045, 3, 1, 7));
const string: SECP384R1_OID is encodeObjectIdentifier([] (1, 3, 132, 0, 34));
const string: SECP521R1_OID is encodeObjectIdentifier([] (1, 3, 132, 0, 35));
const string: MD5_OID is encodeObjectIdentifier([] (1, 2, 840, 113549, 2, 5));
const string: SHA1_OID is encodeObjectIdentifier([] (1, 3, 14, 3, 2, 26));
const string: SHA256_OID is encodeObjectIdentifier([] (2, 16, 840, 1, 101, 3, 4, 2, 1));
const string: SHA384_OID is encodeObjectIdentifier([] (2, 16, 840, 1, 101, 3, 4, 2, 2));
const string: SHA512_OID is encodeObjectIdentifier([] (2, 16, 840, 1, 101, 3, 4, 2, 3));
const integer: KEY_USAGE_DIGITAL_SIGNATURE is 7;
const integer: KEY_USAGE_NON_REPUDIATION is 6;
const integer: KEY_USAGE_KEY_ENCIPHERMENT is 5;
const integer: KEY_USAGE_DATA_ENCIPHERMENT is 4;
const integer: KEY_USAGE_KEY_AGREEMENT is 3;
const integer: KEY_USAGE_KEY_CERT_SIGN is 2;
const integer: KEY_USAGE_CRL_SIGN is 1;
const integer: KEY_USAGE_ENCIPHER_ONLY is 0;
const integer: KEY_USAGE_DECIPHER_ONLY is 15;
const func algorithmIdentifierType: getAlgorithmIdentifier (in string: asn1, inout integer: pos) is func
result
var algorithmIdentifierType: algId is algorithmIdentifierType.value;
local
var asn1DataElement: dataElem is asn1DataElement.value;
var integer: beyond is 0;
begin
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagSequence then
beyond := pos + dataElem.length;
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagObjectIdentifier then
algId.algorithm := getData(asn1, pos, dataElem);
end if;
if pos < beyond then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagObjectIdentifier then
algId.subAlgorithm := getData(asn1, pos, dataElem);
elsif dataElem.tagType = tagSequence then
algId.parameters := getData(asn1, pos, dataElem);
elsif dataElem.tagType <> tagNull then
writeln("*** Unexpected data element " <&
classTagName[ord(dataElem.tagType)] <& " ***");
end if;
end if;
end if;
end func;
const func string: genAlgorithmIdentifier (in algorithmIdentifierType: algId) is func
result
var string: asn1 is "";
begin
asn1 := genAsn1Element(tagObjectIdentifier, algId.algorithm);
if algId.subAlgorithm <> "" then
asn1 &:= genAsn1Element(tagObjectIdentifier, algId.subAlgorithm);
elsif algId.parameters <> "" then
asn1 &:= genAsn1Sequence(algId.parameters);
else
asn1 &:= genAsn1Element(tagNull, "");
end if;
asn1 := genAsn1Sequence(asn1);
end func;
const func rsaKey: getRsaKey (in string: asn1) is func
result
var rsaKey: anRsaKey is rsaKey.value;
local
var integer: pos is 1;
var asn1DataElement: dataElem is asn1DataElement.value;
var bigInteger: modulus is 0_;
var bigInteger: exponent is 0_;
begin
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagSequence then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagInteger then
modulus := bytes2BigInt(getData(asn1, pos, dataElem), UNSIGNED, BE);
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagInteger then
exponent := bytes2BigInt(getData(asn1, pos, dataElem), UNSIGNED, BE);
anRsaKey := rsaKey(modulus, exponent);
end if;
end if;
end if;
end func;
const func string: genX509RsaKey (in rsaKey: anRsaKey) is func
result
var string: asn1 is "";
begin
asn1 := genAsn1Integer(bytes(anRsaKey.modulus, SIGNED, BE));
asn1 &:= genAsn1Integer(bytes(anRsaKey.exponent, SIGNED, BE));
asn1 := genAsn1Sequence(asn1);
end func;
const func rsaSignatureType: getRsaSignature (in string: signatureStri) is func
result
var rsaSignatureType: signature is rsaSignatureType.value;
local
var asn1DataElement: dataElem is asn1DataElement.value;
var integer: pos is 1;
begin
dataElem := getAsn1DataElement(signatureStri, pos);
if dataElem.tagType = tagSequence then
signature.algorithmIdentifier := getAlgorithmIdentifier(signatureStri, pos);
dataElem := getAsn1DataElement(signatureStri, pos);
if dataElem.tagType = tagOctetString then
signature.signature := getData(signatureStri, pos, dataElem);
end if;
end if;
if pos <> succ(length(signatureStri)) then
signature.algorithmIdentifier.algorithm := "";
signature.algorithmIdentifier.subAlgorithm := "";
signature.algorithmIdentifier.parameters := "";
signature.signature := "";
end if;
end func;
const func ecdsaSignatureType: getEcdsaSignature (in string: signatureStri) is func
result
var ecdsaSignatureType: signature is ecdsaSignatureType.value;
local
var asn1DataElement: dataElem is asn1DataElement.value;
var integer: pos is 1;
begin
dataElem := getAsn1DataElement(signatureStri, pos);
if dataElem.tagType = tagSequence then
dataElem := getAsn1DataElement(signatureStri, pos);
if dataElem.tagType = tagInteger then
signature.r := bytes2BigInt(getData(signatureStri, pos, dataElem), UNSIGNED, BE);
dataElem := getAsn1DataElement(signatureStri, pos);
if dataElem.tagType = tagInteger then
signature.s := bytes2BigInt(getData(signatureStri, pos, dataElem), UNSIGNED, BE);
else
signature.r := 0_;
end if;
end if;
end if;
if pos <> succ(length(signatureStri)) then
signature.r := 0_;
signature.s := 0_;
end if;
end func;
const func ellipticCurve: getEllipticCurveFromOid (in string: oid) is func
result
var ellipticCurve: curve is ellipticCurve.value;
begin
if oid = SECP192K1_OID then
curve := secp192k1;
elsif oid = SECP192R1_OID then
curve := secp192r1;
elsif oid = SECP224K1_OID then
curve := secp224k1;
elsif oid = SECP224R1_OID then
curve := secp224r1;
elsif oid = SECP256K1_OID then
curve := secp256k1;
elsif oid = SECP256R1_OID then
curve := secp256r1;
elsif oid = SECP384R1_OID then
curve := secp384r1;
elsif oid = SECP521R1_OID then
curve := secp521r1;
end if;
end func;
const func string: getEllipticCurveOid (in ellipticCurve: curve) is func
result
var string: oid is "";
begin
if curve.name = "secp192k1" then
oid := SECP192K1_OID;
elsif curve.name = "secp192r1" then
oid := SECP192R1_OID;
elsif curve.name = "secp224k1" then
oid := SECP224K1_OID;
elsif curve.name = "secp224r1" then
oid := SECP224R1_OID;
elsif curve.name = "secp256k1" then
oid := SECP256K1_OID;
elsif curve.name = "secp256r1" then
oid := SECP256R1_OID;
elsif curve.name = "secp384r1" then
oid := SECP384R1_OID;
elsif curve.name = "secp512r1" then
oid := SECP521R1_OID;
end if;
end func;
const func ellipticCurve: getEllipticCurve (in string: asn1) is func
result
var ellipticCurve: curve is ellipticCurve.value;
local
var integer: pos is 1;
var asn1DataElement: dataElem is asn1DataElement.value;
var string: data is "";
var boolean: okay is FALSE;
begin
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagInteger and
bytes2Int(getData(asn1, pos, dataElem), UNSIGNED, BE) = 1 then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagSequence then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagObjectIdentifier and
getData(asn1, pos, dataElem) = PRIME_FIELD then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagInteger then
curve.p := bytes2BigInt(getData(asn1, pos, dataElem), UNSIGNED, BE);
curve.bits := bitLength(curve.p);
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagSequence then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagOctetString then
curve.a := bytes2BigInt(getData(asn1, pos, dataElem), UNSIGNED, BE) mod curve.p;
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagOctetString then
curve.b := bytes2BigInt(getData(asn1, pos, dataElem), UNSIGNED, BE) mod curve.p;
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagBitString then
data := getData(asn1, pos, dataElem);
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagOctetString then
curve.g := ecPointDecode(curve, getData(asn1, pos, dataElem));
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagInteger then
curve.n := bytes2BigInt(getData(asn1, pos, dataElem), UNSIGNED, BE);
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagInteger and
bytes2Int(getData(asn1, pos, dataElem), UNSIGNED, BE) = 1 then
okay := TRUE;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
end if;
if not okay then
curve := ellipticCurve.value;
end if;
end func;
const func subjectPublicKeyInfoType: getPublicKeyInfo (in string: asn1, inout integer: pos) is func
result
var subjectPublicKeyInfoType: keyInfo is subjectPublicKeyInfoType.value;
local
var asn1DataElement: dataElem is asn1DataElement.value;
begin
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagSequence then
keyInfo.algorithm := getAlgorithmIdentifier(asn1, pos);
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagBitString then
keyInfo.subjectPublicKey := getData(asn1, pos, dataElem);
if keyInfo.subjectPublicKey[1] <> '\0;' then
writeln("Initial octet of bit-string: " <& ord(keyInfo.subjectPublicKey[1]));
end if;
keyInfo.subjectPublicKey := keyInfo.subjectPublicKey[2 ..];
if keyInfo.algorithm.algorithm = RSA_ENCRYPTION_OID then
keyInfo.publicRsaKey := getRsaKey(keyInfo.subjectPublicKey);
elsif keyInfo.algorithm.algorithm = EC_PUBLIC_KEY then
if keyInfo.algorithm.subAlgorithm <> "" then
keyInfo.eCurve := getEllipticCurveFromOid(keyInfo.algorithm.subAlgorithm);
if keyInfo.eCurve.bits <> 0 then
keyInfo.publicEccKey := ecPointDecode(keyInfo.eCurve, keyInfo.subjectPublicKey);
end if;
else
keyInfo.eCurve := getEllipticCurve(keyInfo.algorithm.parameters);
if keyInfo.eCurve.bits <> 0 then
keyInfo.publicEccKey := ecPointDecode(keyInfo.eCurve, keyInfo.subjectPublicKey);
end if;
end if;
else
writeln("*** Unknown algorithm ***");
end if;
end if;
end if;
end func;
const func string: genX509PublicKeyInfo (in subjectPublicKeyInfoType: keyInfo) is func
result
var string: asn1 is "";
local
var string: subjectPublicKey is "";
begin
asn1 := genAlgorithmIdentifier(keyInfo.algorithm);
if keyInfo.subjectPublicKey <> "" then
subjectPublicKey := keyInfo.subjectPublicKey;
elsif keyInfo.algorithm.algorithm = RSA_ENCRYPTION_OID then
subjectPublicKey := genX509RsaKey(keyInfo.publicRsaKey);
elsif keyInfo.algorithm.algorithm = EC_PUBLIC_KEY then
subjectPublicKey := ecPointEncode(keyInfo.eCurve, keyInfo.publicEccKey);
end if;
asn1 &:= genAsn1Element(tagBitString, "\0;" & subjectPublicKey);
asn1 := genAsn1Sequence(asn1);
end func;
const func x509Name: getX509Name (in string: asn1, inout integer: pos) is func
result
var x509Name: name is x509Name.value;
local
var asn1DataElement: dataElem is asn1DataElement.value;
var integer: posAfterwards is 0;
var string: attrKey is "";
var string: attrValue is "";
begin
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagSequence then
posAfterwards := pos + dataElem.length;
while pos < posAfterwards do
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagSet then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagSequence then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagObjectIdentifier then
attrKey := getData(asn1, pos, dataElem);
end if;
dataElem := getAsn1DataElement(asn1, pos);
attrValue := getData(asn1, pos, dataElem);
if dataElem.tagType = tagUTF8String then
attrValue := fromUtf8(attrValue);
elsif dataElem.tagType = tagBMPString then
attrValue := fromUtf16Be(attrValue);
end if;
name @:= [attrKey] attrValue;
end if;
end if;
end while;
end if;
end func;
const func x509Name: x509Name (in string: commonName,
in string: country, in string: locality, in string: organization,
in string: organizationUnit) is func
result
var x509Name: x509Name is x509Name.value;
begin
if commonName <> "" then
x509Name @:= [COMMON_NAME_OID] commonName;
end if;
if country <> "" then
x509Name @:= [COUNTRY_NAME_OID] country;
end if;
if locality <> "" then
x509Name @:= [LOCALITY_NAME_OID] locality;
end if;
if organization <> "" then
x509Name @:= [ORGANIZATION_NAME_OID] organization;
end if;
if organizationUnit <> "" then
x509Name @:= [ORGANIZATION_UNIT_NAME_OID] organizationUnit;
end if;
end func;
const func string: genX509Name (in x509Name: name) is func
result
var string: asn1 is "";
local
var string: attrKey is "";
var string: attrValue is "";
var string: setElement is "";
begin
for attrValue key attrKey range name do
setElement := genAsn1Element(tagObjectIdentifier, attrKey);
setElement &:= genAsn1String(attrValue);
setElement := genAsn1Sequence(setElement);
asn1 &:= genAsn1Set(setElement);
end for;
asn1 := genAsn1Sequence(asn1);
end func;
const func time: getTime_yymmddhhmmssZ (in string: stri) is func
result
var time: aTime is time.value;
local
var integer: yearInCentury is 0;
var integer: referenceYear is 0;
var integer: referenceCentury is 0;
var integer: possibleYear1 is 0;
var integer: possibleYear2 is 0;
var integer: possibleYear3 is 0;
var integer: diffToYear1 is 0;
var integer: diffToYear2 is 0;
var integer: diffToYear3 is 0;
var integer: year is 0;
begin
yearInCentury := integer(stri[.. 2]);
referenceYear := time(NOW).year;
referenceCentury := referenceYear mdiv 100;
possibleYear1 := pred(referenceCentury) * 100 + yearInCentury;
possibleYear2 := referenceCentury * 100 + yearInCentury;
possibleYear3 := succ(referenceCentury) * 100 + yearInCentury;
diffToYear1 := abs(referenceYear - possibleYear1);
diffToYear2 := abs(referenceYear - possibleYear2);
diffToYear3 := abs(referenceYear - possibleYear3);
if diffToYear1 < diffToYear2 and diffToYear1 < diffToYear3 then
year := possibleYear1;
elsif diffToYear3 < diffToYear1 and diffToYear3 < diffToYear2 then
year := possibleYear3;
else
year := possibleYear2;
end if;
aTime := time(year,
integer(stri[ 3 fixLen 2]),
integer(stri[ 5 fixLen 2]),
integer(stri[ 7 fixLen 2]),
integer(stri[ 9 fixLen 2]),
integer(stri[11 fixLen 2]));
end func;
const func time: getTime_yyyymmddhhmmssfffZ (in string: stri) is func
result
var time: aTime is time.value;
begin
aTime := time(integer(stri[ 1 fixLen 4]),
integer(stri[ 3 fixLen 2]),
integer(stri[ 5 fixLen 2]),
integer(stri[ 7 fixLen 2]),
integer(stri[ 9 fixLen 2]),
integer(stri[11 fixLen 2]));
end func;
const func x509Validity: x509Validity (in time: notBefore, in time: notAfter) is func
result
var x509Validity: validity is x509Validity.value;
begin
validity.notBefore := notBefore;
validity.notAfter := notAfter;
end func;
const func x509Validity: getX509Validity (in string: asn1, inout integer: pos) is func
result
var x509Validity: validity is x509Validity.value;
local
var asn1DataElement: dataElem is asn1DataElement.value;
begin
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagSequence then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagUTCTime then
validity.notBefore := getTime_yymmddhhmmssZ(getData(asn1, pos, dataElem));
elsif dataElem.tagType = tagGeneralizedTime then
validity.notBefore := getTime_yyyymmddhhmmssfffZ(getData(asn1, pos, dataElem));
end if;
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagUTCTime then
validity.notAfter := getTime_yymmddhhmmssZ(getData(asn1, pos, dataElem));
elsif dataElem.tagType = tagGeneralizedTime then
validity.notAfter := getTime_yyyymmddhhmmssfffZ(getData(asn1, pos, dataElem));
end if;
end if;
end func;
const func string: genX509Validity (in x509Validity: validity) is func
result
var string: asn1 is "";
begin
asn1 := genAsn1Element(tagUTCTime, str_yy_mm_dd(validity.notBefore, "") &
str_hh_mm_ss(validity.notBefore, "") & "Z");
asn1 &:= genAsn1Element(tagUTCTime, str_yy_mm_dd(validity.notAfter, "") &
str_hh_mm_ss(validity.notAfter, "") & "Z");
asn1 := genAsn1Sequence(asn1);
end func;
const func tbsCertificateType: getTbsCertificate (in string: asn1, inout integer: pos, in integer: beyond) is func
result
var tbsCertificateType: tbsCertificate is tbsCertificateType.value;
local
var asn1DataElement: dataElem is asn1DataElement.value;
begin
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagClass = contextSpecificTagClass and dataElem.constructed then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagInteger then
tbsCertificate.version := bytes2Int(getData(asn1, pos, dataElem), UNSIGNED, BE);
end if;
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagInteger then
tbsCertificate.serialNumber := getData(asn1, pos, dataElem);
end if;
elsif dataElem.tagType = tagInteger then
tbsCertificate.serialNumber := getData(asn1, pos, dataElem);
end if;
tbsCertificate.signature := getAlgorithmIdentifier(asn1, pos);
tbsCertificate.issuer := getX509Name(asn1, pos);
tbsCertificate.validity := getX509Validity(asn1, pos);
tbsCertificate.subject := getX509Name(asn1, pos);
tbsCertificate.subjectPublicKeyInfo := getPublicKeyInfo(asn1, pos);
if pos < beyond then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.constructed and ord(dataElem.tagType) = 3 then
skipData(pos, dataElem);
end if;
end if;
tbsCertificate.digestEndPos := pred(beyond);
end func;
const func tbsCertificateType: getPkcs7SignedDataCert (in string: asn1, inout integer: pos) is func
result
var tbsCertificateType: tbsCertificate is tbsCertificateType.value;
local
var asn1DataElement: dataElem is asn1DataElement.value;
var integer: version is 0;
var string: digestAlgorithmIdentifiers is "";
var string: contentType is "";
var string: content is "";
var integer: digestStartPos is 0;
begin
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagClass = contextSpecificTagClass and dataElem.constructed then
dataElem := getAsn1DataElement(asn1, pos);
end if;
if dataElem.tagType = tagSequence then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagInteger then
version := bytes2Int(getData(asn1, pos, dataElem), UNSIGNED, BE);
end if;
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagSet then
digestAlgorithmIdentifiers := getData(asn1, pos, dataElem);
end if;
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagSequence then
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagObjectIdentifier then
contentType := getData(asn1, pos, dataElem);
end if;
end if;
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagClass = contextSpecificTagClass and dataElem.constructed then
dataElem := getAsn1DataElement(asn1, pos);
end if;
if dataElem.tagType = tagOctetString then
content := getData(asn1, pos, dataElem);
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagClass = contextSpecificTagClass and dataElem.constructed then
dataElem := getAsn1DataElement(asn1, pos);
end if;
digestStartPos := pos;
dataElem := getAsn1DataElement(asn1, pos);
elsif dataElem.tagType = tagSequence then
digestStartPos := pos;
dataElem := getAsn1DataElement(asn1, pos);
end if;
if dataElem.tagType = tagSequence then
tbsCertificate := getTbsCertificate(asn1, pos, pos + dataElem.length);
tbsCertificate.digestStartPos := digestStartPos;
end if;
end if;
end func;
const func tbsCertificateType: getTbsCertificate (in string: asn1, inout integer: pos) is func
result
var tbsCertificateType: tbsCertificate is tbsCertificateType.value;
local
var asn1DataElement: dataElem is asn1DataElement.value;
var integer: digestStartPos is 0;
begin
digestStartPos := pos;
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagObjectIdentifier then
if getData(asn1, pos, dataElem) = PKCS_7_SIGNED_DATA then
tbsCertificate := getPkcs7SignedDataCert(asn1, pos);
end if;
elsif dataElem.tagType = tagSequence then
tbsCertificate := getTbsCertificate(asn1, pos, pos + dataElem.length);
tbsCertificate.digestStartPos := digestStartPos;
end if;
end func;
const func string: toAsn1 (in x509Extension: extension) is func
result
var string: asn1 is "";
begin
asn1 := genAsn1Element(tagObjectIdentifier, extension.extensionOid);
if extension.isCritical then
asn1 &:= genAsn1Element(tagBoolean, "\255;");
end if;
asn1 &:= genAsn1Element(tagOctetString, extension.octetStringData);
asn1 := genAsn1Sequence(asn1);
end func;
const func string: genX509TbsCertificate (in tbsCertificateType: tbsCertificate) is func
result
var string: asn1 is "";
local
var string: version is "";
var integer: index is 0;
var string: extensions is "";
begin
version := genAsn1Integer(str(chr(tbsCertificate.version)));
asn1 := genExplicitAsn1Tag(0, version);
asn1 &:= genAsn1Integer(tbsCertificate.serialNumber);
asn1 &:= genAlgorithmIdentifier(tbsCertificate.signature);
asn1 &:= genX509Name(tbsCertificate.issuer);
asn1 &:= genX509Validity(tbsCertificate.validity);
asn1 &:= genX509Name(tbsCertificate.subject);
asn1 &:= genX509PublicKeyInfo(tbsCertificate.subjectPublicKeyInfo);
if length(tbsCertificate.extensions) <> 0 then
for index range 1 to length(tbsCertificate.extensions) do
extensions &:= toAsn1(tbsCertificate.extensions[index]);
end for;
extensions := genAsn1Sequence(extensions);
asn1 &:= genExplicitAsn1Tag(3, extensions);
end if;
asn1 := genAsn1Sequence(asn1);
end func;
const func string: getDigestOidFromAlgorithm (in digestAlgorithm: digestAlg) is func
result
var string: digestOid is "";
begin
case digestAlg of
when {MD5}: digestOid := MD5_OID;
when {SHA1}: digestOid := SHA1_OID;
when {SHA256}: digestOid := SHA256_OID;
when {SHA384}: digestOid := SHA384_OID;
when {SHA512}: digestOid := SHA512_OID;
end case;
end func;
const func digestAlgorithm: getDigestAlgorithm (in string: algorithm) is func
result
var digestAlgorithm: digestAlg is NO_DIGEST;
begin
if algorithm = MD5_OID then
digestAlg := MD5;
elsif algorithm = SHA1_OID then
digestAlg := SHA1;
elsif algorithm = SHA256_OID then
digestAlg := SHA256;
elsif algorithm = SHA384_OID then
digestAlg := SHA384;
elsif algorithm = SHA512_OID then
digestAlg := SHA512;
end if;
end func;
const func digestAlgorithm: getDigestFromSignatureAlgorithm (in string: algorithm) is func
result
var digestAlgorithm: digestAlg is NO_DIGEST;
begin
if algorithm = MD5_WITH_RSA_ENCRYPTION then
digestAlg := MD5;
elsif algorithm = SHA1_WITH_RSA_ENCRYPTION then
digestAlg := SHA1;
elsif algorithm = SHA256_WITH_RSA_ENCRYPTION or
algorithm = ECDSA_WITH_SHA256 then
digestAlg := SHA256;
elsif algorithm = SHA384_WITH_RSA_ENCRYPTION or
algorithm = ECDSA_WITH_SHA384 then
digestAlg := SHA384;
elsif algorithm = SHA512_WITH_RSA_ENCRYPTION or
algorithm = ECDSA_WITH_SHA512 then
digestAlg := SHA512;
end if;
end func;
const func string: getDigestOidFromSignatureAlgorithm (in string: algorithm) is func
result
var string: digestOid is "";
begin
if algorithm = MD5_WITH_RSA_ENCRYPTION then
digestOid := MD5_OID;
elsif algorithm = SHA1_WITH_RSA_ENCRYPTION then
digestOid := SHA1_OID;
elsif algorithm = SHA256_WITH_RSA_ENCRYPTION or
algorithm = ECDSA_WITH_SHA256 then
digestOid := SHA256_OID;
elsif algorithm = SHA384_WITH_RSA_ENCRYPTION or
algorithm = ECDSA_WITH_SHA384 then
digestOid := SHA384_OID;
elsif algorithm = SHA512_WITH_RSA_ENCRYPTION or
algorithm = ECDSA_WITH_SHA512 then
digestOid := SHA512_OID;
end if;
end func;
const proc: showSignatureAlgorithm (in string: algorithm) is func
begin
if algorithm = MD5_WITH_RSA_ENCRYPTION then
writeln("MD5 with RSA Encryption");
elsif algorithm = SHA1_WITH_RSA_ENCRYPTION then
writeln("SHA-1 with RSA Encryption");
elsif algorithm = SHA256_WITH_RSA_ENCRYPTION then
writeln("SHA-256 with RSA Encryption");
elsif algorithm = SHA384_WITH_RSA_ENCRYPTION then
writeln("SHA-384 with RSA Encryption");
elsif algorithm = SHA512_WITH_RSA_ENCRYPTION then
writeln("SHA-512 with RSA Encryption");
elsif algorithm = ECDSA_WITH_SHA256 then
writeln("ECDSA with SHA-256");
elsif algorithm = ECDSA_WITH_SHA384 then
writeln("ECDSA with SHA-384");
elsif algorithm = ECDSA_WITH_SHA512 then
writeln("ECDSA with SHA-512");
else
writeln("Unknown: " <& literal(algorithm));
end if;
end func;
const func x509Cert: getX509Cert (in string: asn1) is func
result
var x509Cert: cert is x509Cert.value;
local
var integer: pos is 1;
var asn1DataElement: dataElem is asn1DataElement.value;
var digestAlgorithm: digestAlg is NO_DIGEST;
begin
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagSequence then
cert.tbsCertificate := getTbsCertificate(asn1, pos);
end if;
cert.signatureAlgorithm := getAlgorithmIdentifier(asn1, pos);
dataElem := getAsn1DataElement(asn1, pos);
if dataElem.tagType = tagBitString then
cert.signatureValue := getData(asn1, pos, dataElem)[2 ..];
digestAlg := getDigestFromSignatureAlgorithm(cert.signatureAlgorithm.algorithm);
if digestAlg <> NO_DIGEST then
cert.messageDigest := msgDigest(digestAlg,
asn1[cert.tbsCertificate.digestStartPos .. cert.tbsCertificate.digestEndPos]);
end if;
end if;
end func;
const func string: genX509Cert (inout x509Cert: cert, in rsaKey: issuerKey) is func
result
var string: asn1 is "";
local
var digestAlgorithm: digestAlg is NO_DIGEST;
var algorithmIdentifierType: digestAlgorithmId is algorithmIdentifierType.value;
var string: signature is "";
begin
asn1 := genX509TbsCertificate(cert.tbsCertificate);
digestAlg := getDigestFromSignatureAlgorithm(cert.signatureAlgorithm.algorithm);
if digestAlg <> NO_DIGEST then
cert.messageDigest := msgDigest(digestAlg, asn1);
end if;
digestAlgorithmId.algorithm :=
getDigestOidFromSignatureAlgorithm(cert.signatureAlgorithm.algorithm);
signature := genAlgorithmIdentifier(digestAlgorithmId);
signature &:= genAsn1Element(tagOctetString, cert.messageDigest);
signature := genAsn1Sequence(signature);
cert.signatureValue := rsassaPkcs1V15Encrypt(issuerKey, signature);
asn1 &:= genAlgorithmIdentifier(cert.signatureAlgorithm);
asn1 &:= genAsn1Element(tagBitString, "\0;" & cert.signatureValue);
asn1 := genAsn1Sequence(asn1);
end func;
const func string: genX509Cert (inout x509Cert: cert, in ellipticCurve: curve,
in bigInteger: issuerKey) is func
result
var string: asn1 is "";
local
var digestAlgorithm: digestAlg is NO_DIGEST;
var algorithmIdentifierType: digestAlgorithmId is algorithmIdentifierType.value;
var ecdsaSignatureType: ecdsaSignature is ecdsaSignatureType.value;
begin
asn1 := genX509TbsCertificate(cert.tbsCertificate);
digestAlg := getDigestFromSignatureAlgorithm(cert.signatureAlgorithm.algorithm);
if digestAlg <> NO_DIGEST then
cert.messageDigest := msgDigest(digestAlg, asn1);
end if;
digestAlgorithmId.algorithm :=
getDigestOidFromSignatureAlgorithm(cert.signatureAlgorithm.algorithm);
ecdsaSignature := sign(curve, bytes2BigInt(cert.messageDigest, UNSIGNED, BE), issuerKey);
cert.signatureValue := genAsn1Sequence(
genAsn1Integer(bytes(ecdsaSignature.r, UNSIGNED, BE)) &
genAsn1Integer(bytes(ecdsaSignature.s, UNSIGNED, BE)));
asn1 &:= genAlgorithmIdentifier(cert.signatureAlgorithm);
asn1 &:= genAsn1Element(tagBitString, "\0;" & cert.signatureValue);
asn1 := genAsn1Sequence(asn1);
end func;
const func boolean: validateSignature (in x509Cert: cert, in subjectPublicKeyInfoType: publicKey) is func
result
var boolean: okay is FALSE;
local
var digestAlgorithm: digestAlg is NO_DIGEST;
var string: decrypted is "";
var rsaSignatureType: rsaSignature is rsaSignatureType.value;
begin
digestAlg := getDigestFromSignatureAlgorithm(cert.signatureAlgorithm.algorithm);
if digestAlg <> NO_DIGEST then
block
if publicKey.algorithm.algorithm = RSA_ENCRYPTION_OID then
decrypted := rsassaPkcs1V15Decrypt(publicKey.publicRsaKey, cert.signatureValue);
rsaSignature := getRsaSignature(decrypted);
okay := digestAlg = getDigestAlgorithm(rsaSignature.algorithmIdentifier.algorithm) and
cert.messageDigest = rsaSignature.signature;
elsif publicKey.algorithm.algorithm = EC_PUBLIC_KEY then
okay := verify(publicKey.eCurve, bytes2BigInt(cert.messageDigest, UNSIGNED, BE),
getEcdsaSignature(cert.signatureValue), publicKey.publicEccKey);
end if;
exception
otherwise: okay := FALSE;
end block;
end if;
end func;
const func x509Cert: createX509Cert (in rsaKey: publicRsaKey,
in bigInteger: serialNumber, in x509Name: issuer,
in x509Name: subject, in x509Validity: validity) is func
result
var x509Cert: cert is x509Cert.value;
begin
cert.tbsCertificate.version := 0;
cert.tbsCertificate.serialNumber := bytes(serialNumber, UNSIGNED, BE);
cert.tbsCertificate.signature.algorithm := SHA256_WITH_RSA_ENCRYPTION;
cert.tbsCertificate.issuer := issuer;
cert.tbsCertificate.validity := validity;
cert.tbsCertificate.subject := subject;
cert.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm := RSA_ENCRYPTION_OID;
cert.tbsCertificate.subjectPublicKeyInfo.publicRsaKey := publicRsaKey;
cert.signatureAlgorithm.algorithm := SHA256_WITH_RSA_ENCRYPTION;
end func;
const func x509Cert: createX509Cert (in rsaKey: publicRsaKey,
in bigInteger: serialNumber, in string: commonName, in string: country,
in string: locality, in string: organization,
in string: organizationUnit, in x509Validity: validity) is func
result
var x509Cert: cert is x509Cert.value;
begin
cert.tbsCertificate.version := 0;
cert.tbsCertificate.serialNumber := bytes(serialNumber, UNSIGNED, BE);
cert.tbsCertificate.signature.algorithm := SHA256_WITH_RSA_ENCRYPTION;
cert.tbsCertificate.issuer @:= [COMMON_NAME_OID] commonName;
cert.tbsCertificate.issuer @:= [COUNTRY_NAME_OID] country;
cert.tbsCertificate.issuer @:= [LOCALITY_NAME_OID] locality;
cert.tbsCertificate.issuer @:= [ORGANIZATION_NAME_OID] organization;
cert.tbsCertificate.issuer @:= [ORGANIZATION_UNIT_NAME_OID] organizationUnit;
cert.tbsCertificate.validity := validity;
cert.tbsCertificate.subject @:= [COMMON_NAME_OID] commonName;
cert.tbsCertificate.subject @:= [COUNTRY_NAME_OID] country;
cert.tbsCertificate.subject @:= [LOCALITY_NAME_OID] locality;
cert.tbsCertificate.subject @:= [ORGANIZATION_NAME_OID] organization;
cert.tbsCertificate.subject @:= [ORGANIZATION_UNIT_NAME_OID] organizationUnit;
cert.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm := RSA_ENCRYPTION_OID;
cert.tbsCertificate.subjectPublicKeyInfo.publicRsaKey := publicRsaKey;
cert.signatureAlgorithm.algorithm := SHA256_WITH_RSA_ENCRYPTION;
end func;
const func x509Cert: createX509Cert (in ellipticCurve: curve,
in ecPoint: publicEccKey, in bigInteger: serialNumber, in x509Name: issuer,
in x509Name: subject, in x509Validity: validity) is func
result
var x509Cert: cert is x509Cert.value;
begin
cert.tbsCertificate.version := 0;
cert.tbsCertificate.serialNumber := bytes(serialNumber, UNSIGNED, BE);
cert.tbsCertificate.signature.algorithm := ECDSA_WITH_SHA256;
cert.tbsCertificate.issuer := issuer;
cert.tbsCertificate.validity := validity;
cert.tbsCertificate.subject := subject;
cert.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm := EC_PUBLIC_KEY;
cert.tbsCertificate.subjectPublicKeyInfo.algorithm.subAlgorithm := getEllipticCurveOid(curve);
cert.tbsCertificate.subjectPublicKeyInfo.eCurve := curve;
cert.tbsCertificate.subjectPublicKeyInfo.publicEccKey := publicEccKey;
cert.signatureAlgorithm.algorithm := ECDSA_WITH_SHA256;
end func;
const func x509Cert: createX509Cert (in ellipticCurve: curve,
in ecPoint: publicEccKey, in bigInteger: serialNumber, in string: commonName,
in string: country, in string: locality, in string: organization,
in string: organizationUnit, in x509Validity: validity) is func
result
var x509Cert: cert is x509Cert.value;
begin
cert.tbsCertificate.version := 0;
cert.tbsCertificate.serialNumber := bytes(serialNumber, UNSIGNED, BE);
cert.tbsCertificate.signature.algorithm := ECDSA_WITH_SHA256;
cert.tbsCertificate.issuer @:= [COMMON_NAME_OID] commonName;
cert.tbsCertificate.issuer @:= [COUNTRY_NAME_OID] country;
cert.tbsCertificate.issuer @:= [LOCALITY_NAME_OID] locality;
cert.tbsCertificate.issuer @:= [ORGANIZATION_NAME_OID] organization;
cert.tbsCertificate.issuer @:= [ORGANIZATION_UNIT_NAME_OID] organizationUnit;
cert.tbsCertificate.validity := validity;
cert.tbsCertificate.subject @:= [COMMON_NAME_OID] commonName;
cert.tbsCertificate.subject @:= [COUNTRY_NAME_OID] country;
cert.tbsCertificate.subject @:= [LOCALITY_NAME_OID] locality;
cert.tbsCertificate.subject @:= [ORGANIZATION_NAME_OID] organization;
cert.tbsCertificate.subject @:= [ORGANIZATION_UNIT_NAME_OID] organizationUnit;
cert.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm := EC_PUBLIC_KEY;
cert.tbsCertificate.subjectPublicKeyInfo.algorithm.subAlgorithm := getEllipticCurveOid(curve);
cert.tbsCertificate.subjectPublicKeyInfo.eCurve := curve;
cert.tbsCertificate.subjectPublicKeyInfo.publicEccKey := publicEccKey;
cert.signatureAlgorithm.algorithm := ECDSA_WITH_SHA256;
end func;
const func x509Extension: x509KeyUsage (in bitset: keyUsage) is func
result
var x509Extension: keyUsageExtension is x509Extension.value;
local
var string: bits is "";
begin
keyUsageExtension.extensionOid := KEY_USAGE_OID;
bits := bytes(integer(keyUsage), UNSIGNED, LE);
keyUsageExtension.octetStringData := genAsn1Element(tagBitString,
str(char(lowestSetBit(ord(bits[length(bits)])))) & bits);
end func;
const func x509Extension: x509BasicConstraints (in integer: pathLenConstraint) is func
result
var x509Extension: basicConstraintsExtension is x509Extension.value;
begin
basicConstraintsExtension.extensionOid := BASIC_CONSTRAINTS_OID;
basicConstraintsExtension.octetStringData := genAsn1Sequence(
genAsn1Element(tagBoolean, "\255;") &
genAsn1Integer(bytes(pathLenConstraint, SIGNED, BE)));
end func;
const func x509Extension: x509BasicConstraints (in boolean: cA) is func
result
var x509Extension: basicConstraintsExtension is x509Extension.value;
begin
basicConstraintsExtension.extensionOid := BASIC_CONSTRAINTS_OID;
basicConstraintsExtension.octetStringData := genAsn1Sequence(
cA ? genAsn1Element(tagBoolean, "\255;") : "");
end func;
const proc: addExtension (inout x509Cert: cert, in boolean: isCritical,
in var x509Extension: extension) is func
begin
extension.isCritical := isCritical;
cert.tbsCertificate.extensions &:= extension;
end func;
const func certAndKey: certAndKey (in array string: certList, in rsaKey: privateRsaKey) is func
result
var certAndKey: certificate is certAndKey.value;
begin
certificate.certList := certList;
certificate.privateRsaKey := privateRsaKey;
end func;
const func certAndKey: certAndKey (in array string: certList, in bigInteger: privateEccKey) is func
result
var certAndKey: certificate is certAndKey.value;
begin
certificate.certList := certList;
certificate.privateEccKey := privateEccKey;
end func;
const func certAndKey: selfSignedX509Cert (in rsaKeyPair: keyPair,
in bigInteger: serialNumber, in string: commonName, in string: country,
in string: locality, in string: organization,
in string: organizationUnit, in x509Validity: validity) is func
result
var certAndKey: certificate is certAndKey.value;
local
var x509Cert: cert is x509Cert.value;
begin
cert := createX509Cert(keyPair.publicKey, serialNumber, commonName,
country, locality, organization, organizationUnit,
validity);
certificate.certList := [] (genX509Cert(cert, keyPair.privateKey));
certificate.privateRsaKey := keyPair.privateKey;
end func;
const func certAndKey: selfSignedX509Cert (in string: commonName,
in string: country, in string: locality, in string: organization,
in string: organizationUnit) is
return selfSignedX509Cert(genRsaKeyPair(2048, 16#10001_),
rand(0_, 2_ ** (20 * 8) - 1_), commonName,
country, locality, organization, organizationUnit,
x509Validity(time(NOW) - 1 . YEARS,
time(NOW) + 1 . YEARS));
const certAndKey: stdCertificate is selfSignedX509Cert(
stdRsaKeyPair, 6_, "localhost",
"AT", "Vienna", "Black Hole", "Super Massive",
x509Validity(date(2022, 1, 1), date(2026, 1, 1)));
const func certAndKey: selfSignedX509Cert (in eccKeyPair: keyPair,
in bigInteger: serialNumber, in string: commonName, in string: country,
in string: locality, in string: organization,
in string: organizationUnit, in x509Validity: validity) is func
result
var certAndKey: certificate is certAndKey.value;
local
var x509Cert: cert is x509Cert.value;
begin
cert := createX509Cert(keyPair.curve, keyPair.publicKey, serialNumber,
commonName, country, locality, organization,
organizationUnit, validity);
certificate.certList := [] (genX509Cert(cert, keyPair.curve, keyPair.privateKey));
certificate.privateEccKey := keyPair.privateKey;
end func;
const certAndKey: stdEccCertificate is selfSignedX509Cert(
stdEccKeyPair, 1_, "localhost",
"AT", "Vienna", "Black Hole", "Super Massive",
x509Validity(date(2023, 1, 1), date(2028, 1, 1)));