public static Certificate converyNativeCert(CertificateStr nativeCert, byte[] encodedCertValue)
        {
            Certificate certificate = new Certificate();

            certificate.AuthorityKeyIdentifier = nativeCert.AuthorityKeyIdentifier;
            certificate.BasicConstraints       = nativeCert.BasicConstraints;
            certificate.DNsNames              = convertStringMapToArray(nativeCert.DnsNames);
            certificate.EmailAddresses        = convertStringMapToArray(nativeCert.EmailAddresses);
            certificate.ExtendedKeyUsage      = convertExtendedKeyUsage(nativeCert.ExtendedKeyUsage);
            certificate.IpAddresses           = convertStringMapToArray(nativeCert.IpAddresses);
            certificate.Issuer                = convertNativeName(nativeCert.issuer);
            certificate.Subject               = convertNativeName(nativeCert.subject);
            certificate.KeyUsage              = convertKeyUsage(nativeCert.KeyUsage);
            certificate.PublicKeyAlgName      = nativeCert.PublicKeyAlgName;
            certificate.SerialNumber          = Helper.AsBigInteger(nativeCert.SerialNumber); // todo : possibly problematic
            certificate.Signature             = nativeCert.Signature;
            certificate.SignatureAlgorithm    = nativeCert.SignatureAlgorithm;
            certificate.SubjectKeyIdentifier  = nativeCert.SubjectKeyIdentifier;
            certificate.SubjectPublicKeyInfo  = nativeCert.SubjectPublicKeyInfo;
            certificate.TbsCertificate        = nativeCert.TbsCertificate;
            certificate.TBSSignatureAlgorithm = nativeCert.TBSSignatureAlgorithm;
            certificate.Urls         = convertStringMapToArray(nativeCert.Urls);
            certificate.Validity     = nativeCert.Validity;
            certificate.Version      = nativeCert.Version;
            certificate.IsLoaded     = true;
            certificate.EncodedValue = encodedCertValue;
            return(certificate);
        }
        public static void print(CertificateStr cert)
        {
            Runtime.Notify("test", "version", 0, cert.Version);
            Runtime.Notify("test", "serialNumber", 1, cert.SerialNumber);
            print(cert.issuer, "issuer");
            print(cert.subject, "subject");
            Runtime.Notify("test", "notBefore", 2, cert.Validity.NotBefore);
            Runtime.Notify("test", "notAfter", 2, cert.Validity.NotAfter);
            Runtime.Notify("test", "extendedKeyUsageCount", 0, cert.ExtendedKeyUsage.Count);
            print(cert.ExtendedKeyUsage.Oids, "extendedKeyUsageOids");
            Runtime.Notify("test", "keyUsage", 0, cert.KeyUsage.Value);
            Runtime.Notify("test", "basicContraintsValid", 3, cert.BasicConstraints.HasBasicConstraints);
            Runtime.Notify("test", "isCa", 3, cert.BasicConstraints.IsCa);
            Runtime.Notify("test", "maxPathLen", 0, cert.BasicConstraints.MaxPathLen);
            Runtime.Notify("test", "hasAuthorityKeyIdentifier", 3,
                           cert.AuthorityKeyIdentifier.HasAuthorityKeyIdentifier);
            Runtime.Notify("test", "authorityKeyId", 1, cert.AuthorityKeyIdentifier.keyIdentifier);
            Runtime.Notify("test", "subjectKeyId", 1, cert.SubjectKeyIdentifier.keyIdentifier);

            print(cert.DnsNames, "dnsName");
            print(cert.EmailAddresses, "emailAddresses");
            print(cert.IpAddresses, "ipAddresses");
            print(cert.Urls, "urls");

            Runtime.Notify("test", "tbsCertificate", 1, cert.TbsCertificate);
            Runtime.Notify("test", "signatureAlgorithm", 1, cert.SignatureAlgorithm);
            Runtime.Notify("test", "signatureValue", 1, cert.Signature);
            Runtime.Notify("test", "subjectPublicKeyInfo", 1, cert.SubjectPublicKeyInfo);

            Runtime.Notify("test", "publicKeySignatureAlgorithm", 1, cert.PublicKeyAlgName);
            Runtime.Notify("test", "tbsCertificateSignatureAlgorithm", 1, cert.TBSSignatureAlgorithm);
        }
        public static Certificate parse(byte[] encodedCertValue)
        {
            ParseCertParam param = new ParseCertParam {
            };

            param.asnData = encodedCertValue;
            byte[]         parsedData  = callNativeContract(param);
            CertificateStr cert        = Deserialization.deserializeCertData(parsedData);
            Certificate    certificate = NativeMapper.converyNativeCert(cert, encodedCertValue);

            return(certificate);
        }
        public static CertificateStr deserializeCertData(byte[] raw)
        {
            int            length = raw.Length;
            int            idx    = 0;
            CertificateStr cert   = new CertificateStr();

            cert.Version = readInt(raw, idx);
            idx         += 4;

            DeserializationFieldResult serialNumber = readByteArray(raw, idx);

            cert.SerialNumber = (byte[])serialNumber.value;
            idx += serialNumber.size;

            DeserializationFieldResult issuer = deserializeName(raw, idx);

            cert.issuer = (NameStr)issuer.value;
            idx        += issuer.size;

            DeserializationFieldResult subject = deserializeName(raw, idx);

            cert.subject = (NameStr)subject.value;
            idx         += subject.size;

            Validity validity = new Validity();

            validity.NotBefore = readLong(raw, idx); //check
            idx += 8;

            validity.NotAfter = readLong(raw, idx); //check
            idx          += 8;
            cert.Validity = validity;

            NativeExtendedKeyUsage extendedKeyUsage = new NativeExtendedKeyUsage();

            extendedKeyUsage.Count = readInt(raw, idx);
            idx += 4;

            DeserializationFieldResult extendedKeyUsageOIDs = readStringArray(raw, idx);

            extendedKeyUsage.Oids = (CMap <int, string>)extendedKeyUsageOIDs.value;
            idx += extendedKeyUsageOIDs.size;
            cert.ExtendedKeyUsage = extendedKeyUsage;

            NativeKeyUsage keyUsage = new NativeKeyUsage();

            keyUsage.Value = readInt(raw, idx);
            idx           += 4;
            cert.KeyUsage  = keyUsage;

            BasicConstraints basicConstraints = new BasicConstraints();

            basicConstraints.HasBasicConstraints = readBool(raw, idx);
            idx += 1;

            basicConstraints.IsCa = readBool(raw, idx);
            idx += 1;

            basicConstraints.MaxPathLen = readInt(raw, idx); //check FF FF FF FF becomes FF FF FE FE
            idx += 4;
            cert.BasicConstraints = basicConstraints;

            AuthorityKeyIdentifier     authorityKeyIdentifier = new AuthorityKeyIdentifier();
            DeserializationFieldResult authorityKeyId         = readByteArray(raw, idx);

            authorityKeyIdentifier.keyIdentifier = (byte[])authorityKeyId.value;
            if (authorityKeyId.size > 2)
            {
                authorityKeyIdentifier.HasAuthorityKeyIdentifier = true;
            }

            idx += authorityKeyId.size;
            cert.AuthorityKeyIdentifier = authorityKeyIdentifier;

            SubjectKeyIdentifier       subjectKeyIdentifier = new SubjectKeyIdentifier();
            DeserializationFieldResult subjectKeyId         = readByteArray(raw, idx);

            subjectKeyIdentifier.keyIdentifier = (byte[])subjectKeyId.value;
            if (subjectKeyId.size > 2)
            {
                subjectKeyIdentifier.HasSubjectKeyIdentifierExtension = true;
            }

            idx += subjectKeyId.size;
            cert.SubjectKeyIdentifier = subjectKeyIdentifier;

            DeserializationFieldResult dnsNames = readStringArray(raw, idx);

            cert.DnsNames = (CMap <int, string>)dnsNames.value;
            idx          += dnsNames.size;

            DeserializationFieldResult emailAddresses = readStringArray(raw, idx);

            cert.EmailAddresses = (CMap <int, string>)emailAddresses.value;
            idx += emailAddresses.size;

            DeserializationFieldResult ipAddresses = readStringArray(raw, idx);

            cert.IpAddresses = (CMap <int, string>)ipAddresses.value;
            idx += ipAddresses.size;

            DeserializationFieldResult urls = readStringArray(raw, idx);

            cert.Urls = (CMap <int, string>)urls.value;
            idx      += urls.size;

            DeserializationFieldResult tbsCertificate = readByteArray(raw, idx);

            cert.TbsCertificate = (byte[])tbsCertificate.value;
            idx += tbsCertificate.size;

            DeserializationFieldResult signatureAlgorithm = readByteArray(raw, idx);

            cert.SignatureAlgorithm = (byte[])signatureAlgorithm.value;
            idx += signatureAlgorithm.size;

            DeserializationFieldResult signatureValue = readByteArray(raw, idx);

            cert.Signature = (byte[])signatureValue.value;
            idx           += signatureValue.size;

            DeserializationFieldResult subjectPublicKeyInfo = readByteArray(raw, idx);

            cert.SubjectPublicKeyInfo = (byte[])subjectPublicKeyInfo.value;
            idx += subjectPublicKeyInfo.size;

            DeserializationFieldResult publicKeySignatureAlgorithm = readByteArray(raw, idx);

            cert.PublicKeyAlgName = (byte[])publicKeySignatureAlgorithm.value;
            idx += publicKeySignatureAlgorithm.size;

            DeserializationFieldResult tbsCertificateSignatureAlgorithm = readByteArray(raw, idx);

            cert.TBSSignatureAlgorithm = (byte[])tbsCertificateSignatureAlgorithm.value;
            idx += tbsCertificateSignatureAlgorithm.size;

            // todo return byte[] ?
            return(cert);
        }