博客專欄

        EEPW首頁 > 博客 > 13.openssl編程——ASN1庫

        13.openssl編程——ASN1庫

        發布人:電子禪石 時間:2024-06-19 來源:工程師 發布文章
        13.1  ASN1簡介
        ANS.1(Abstract Syntax Notation One, X.208),是一套靈活的標記語言,他允許定義多種數據類型,從integer、bit string、一類的簡單類型到結構化類型,如set和sequence,并且可以使用這些類型構建復雜類型。
        DER編碼是ANS.1定義的將對象描述數據編碼成8位串值的編碼規則,他給出了對ANS.1值(對象的類型和值)的唯一編碼規則。
         
        a  簡單類型
                             BIT STRING  任意0、1位串;
                             IA5String      任意IA5(ASCII)字符串;
                             INTEGER   任意一個整數;
                             NULL      空值;
                             OBJECT IDENTIFIER 一個對象標識號(一串整數),標識算法或屬性類型等對象;
                             OCTET STRING 8位串;
                             PrintableString       任意可打印字符串;
                             T61String       任意T.61(8位)字符串;
                             UTCTime       一個“協同世界時”或“格林威治標準時(G.M.T)”。
        b    結構類型
                             結構類型由組件組成,ANS.1定義了四種結構類型:
                             SEQUENCE                  一個或多個類型的有序排列;
                             SEQUENCE OF            一個給定類型的0個或多個有序排列;
                             SET                             一個或多個類型的無序集合;
                             SET OF                     一個給定類型的0個或多個無序集合。
               c    帶標記類型
        在一個應用內部區分類型的有效方法是使用標記,標記也同樣用于區分一個結構類型內部不同的組件。例如SET或SEQUENCE類型可選項通常使用上下文標記以避免混淆。有兩種標記類型的方法:隱式和顯式。隱式標記類型是將其它類型的標記改變,得到新的類型。隱式標記的關鍵字是IMPLICIT。顯式標記類型是將其它類型加上一個外部標記,得到新的類型。顯式標記的關鍵字是EXPLICIT。
        為了進行編碼,隱式標記類型除了標記不同以外,可以視為與其基礎類型相同。顯式標記類型可以視為只有一個組件的結構類型。
              d    其它類型
        類型和值用符號::=表示,符號左邊的是名字,右邊是類型和值。名字又可以用于定義其它的類型和值。
        除了CHOICE類型、ANY類型以外,所有ANS.1類型都有一個標記,標記由一個類和一個非負的標記碼組成,當且僅當標記碼相同時,ANS.1類型是相同的。也就是說,影響其抽象意義的不是ANS.1類型的名字,而是其標記。
         
        13.2 DER編碼
        DER給出了一種將ASN.1值為8位串的方法。DER編碼包含三個部分:
        標識(一個或多個8位串):定義值的類和標記碼,指出是原始編碼還是結構化編碼
        長度(一個或多個8位串):對于定長編碼,指出內容中8位串的個數;對于不定長編碼
        內容(一個或多個8位串):對于原始定長編碼,給出真實值,對于結構化編碼,給出個串聯結果
        內容結束(一個或多個8位串):對于結構化不定長編碼,標識內容結束,對于其他編碼,無此項。
         
        13.3 ANS1基本類型示例
        a.ANS1_BOOLEAN
        表明ASN1語法中的true和flase。
        其中0x01 (表示為BOOLEAN) 0x01(表示后面值的長度) 0x00(值)為本例BOOLEANDER編碼。
         
        b.ANS1_OBJECT
        ANS1中OBJECT表明一個對象,每個對象有一個OID(object id)
        其中0x06(表示為OBJECT類型) 0x03(值的長度) 0x55 0x04 0x0A
         
        c.ASN1_INTEGER
        ANS1中的INTEGER類型用于表示整數。
        其內容為:0x30 0x03 0x02(整數) 0x01 (整數值長度)0x55 (整數值)
         
        d.ASN1_ENUMERATED
         
        e. ASN1_BIT_STRING
        0x01 0x02的DER編碼:0x03(BIT STRING 類型) 0x02(長度) 0x01 0x02(比特值)
         
        f.ANS1_OCTET_STRING
        0x04(OCTET STRING) 0x02(長度) 0x01 0x02(值)
         
        g.ASN1_PRINGTABLESTRING
        可打印字符
        0x13(PRINTABLESTRING) 0x04(長度) 0x61 0x73 0x6E 0X31(即"asn1")
         
        ASN1_UTCTIME:表示時間
        ASN1_GENERALIZEDTIME:表示時間
        ASN1_VISIBLESTRING:存放可見字符
        ASN1_UTF8STRING:用于存放utf8字符串,存放漢子需要將漢子轉換utf8字符串
        ASN1_TYPE:用于存放任意類型
         
        13.4 openssl的ASN.1庫
        typedef struct asn1_string_st ASN1_INTGER;
        ASN1_INTEGER
        ASN1_ENUMERATED
        ASN1_BIT_STRING
        ASN1_OCTET_STRING
        ASN1_PRINTABLESTRING
        ASN1_T61STRING
        ASN1_IAS5STRING
        ASN1_UTCTIME
        ASN1_GENERALIZEDTIME
        ASN1_TIME
        ASN1_GENERALSTRING
        ASN1_TIME
        ASN1_GENERALSTRING
        ASN1_UNIVERSALSTRING
        ASN1_BMPSTRING
        ASN1_VISIBLESTRING
        ASN1_UTF8STRING
        ASN1_BOOLEAN
        ASN1_NULL
         
        四種基本的函數
        new:用于生成一個新的數據結構
        free:用于釋放該結構
        i2d:用于將該內部數據結構轉換成DER編碼
        d2i:用于將DER編碼轉換成內部數據結構
         
        ASN1_INTEGER_ASN1_INTEGER_new(void);
        void *ASN1_INTEGER_free(ASN1_INTEGER *a)
        ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, unsigned char **in, long ,len)
        int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **out);
        long ASN1_INTEGER_get(ASN1_INTEGER *a)
        int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
         
        13.5 用openssl的ASN.1庫DER編解碼
        當采用openssl的ASN.1庫編碼一個asn.1定義結構的時候,需要采用如下步驟
        a.用ASN.1語法定義內部數據結構,并聲明函數
        所謂內部數據結構,指的是openssl中用基本的數據類型按照ASN.1語法數據結構
        以x509v4中正數有效期為例,正數有效期定義如下:
        AttCertValidityPeriod::= SEQUENCE
        {
        notBeforeTime GeneralizedTime,
        notAfterTime GenerailizedTime,
        }
         
        我們定義相應內部數據結構
        typedef struct X509V4_VALID_st
        {
        ASN1_GENERALIZEDTIME *notBefore;
        ASN1_GENERALIZEDTIME *notAfter;
        } X509V4_VALID;
        DECLARE_ASN1_FUNCTIONS(X509V4_VALID)
        其中最后一行用于定義四個函數
        X509V4_VALID *X509V4_VALID_new(void);
        void *X509V4_VALID_free(X509V4_VALID *a);
        X509V4_VALID *d2i_ASN1_INTEGER(X509V4_VALID **a, unsgined char **in, long len);
         
        b. 實現內部數據結構的四個基本函數
        實現內部數據結構的基本函數,是通過一系列的紅來實現的。定義的模式如下,定義的模式如下,以屬性證書有效期為例,
        /*X509V4_VALID*/
        ASN1_SEQUENCE(X509V4_VALID) =
        {
        ASN1_SIMPLE(X509V4_VALID, notBefore, ASN1_GENERALIZEDTIME),
        ASN1_SIMPLE(X509V4_VALID, notAfter, ASN1_GENERALIZEDTIME)
        } ASN1_SEQUNCE_END(X509V4_VALID)
        IMPLEMENT_ASN1_FUNCTIONS(X509V4_VALID)
        這樣通過宏實現了一個asn.1定義結構的最基本的四個函數
         
        13.6 Openssl的ASN.1宏
        openssl中ASN.1宏用來定義某種內部數據結構以及這種結構如何編碼,部分宏定義說明如下
        a.DECLARE_ASN1_FUNCTIONS
        用于聲明一個內部數據結構的四個基本函數,一般可以在頭文件中定義。
        b.IMPLEMENT_ASN1_FUNCTIONS
        用于實現一個數據結構的四個基本函數
        c.ASN1_SEQUENCE
        用于SEQUENCE,表明下面的編碼是一個SEQUENCE.
        d.ASN1_CHOICE
        表明下面的編碼是選擇其中一項,為CHOICE類型
        e.ASN1_SIMPLE
        用于簡單類型或結構類型,并且是必須項。
        f.ANS1_OPT
        用于可選項,表明asn.1語法中,本項可選的。
        g.ANS1_EXP_OPT
        用于顯示標記,表明asn.1語法中,本項是顯示類型,并且是可選的。
        h.ASN1_EXP
        用于顯示標記,表明asn.1語法中,本項是顯示標記
        i.ASN1_IMP_SEQUENCE_OF_OPT
        用于隱示標記,表明asn.1語法中,本項是一個SEQUENCE序列,為隱的。
        j.ASN1_IMP_OPT
        用于隱示標記,表明asn.1語法中,本想是隱示類型,并且是可選的。
        k.ASN1_SEQUENCE_END
        用于SEQUENCE結束
        l.ASN1_CHOICE_END
        用于結束CHOICE類型。
         
        13.7 ASN1常用函數
        ANS1的基本數據類型如下函數:new, free, i2d, d2i, i2a a2i print set get cmp和dup。
        new函數用于分配空間,生成ASN1數據結構
        free用于釋放空間
        i2d函數用于ASN1數據結構轉換為DER編碼
        d2i將DER編碼轉換為ASN1數據結構
        i2a將內部結構轉換為ASCII碼
        a2i將ASCII碼轉換為內部數據結構
        set函數用于設置ASN1類型的值
        get函數用于獲取ASN1類型值
        print將ASN1類型打印
        cmp用于比較ASN1數據結構
        dup函數進行數據結構的拷貝。
         
        常用的函數有:
        a.int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
        功能:計算OID的DER編碼
        b.int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
        功能:將bp中ASC碼轉換為ASN1_INTEGER,buf存放BIO中ASC碼
        c.int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
        功能:將ASCII碼轉換為ASN1_STRING
        d.unsigned char *asc2uni(const char *asc, int asclen, usngined char **uni, int *unilen)
        功能:將ASCII碼轉換為unicode
        e.int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
        功能:本函數根據n獲取比特位上的值
        f.ASN1_BIT_STRING_set
        設置ASN1_BIT_STRING的值,他調用ASN1_STRING_set函數
        g.void *ASN1_d2i_bio(void *(xnew)(void), d2i_of_void *d2i, BIO *in, void **x)
        對bio的數據DER解碼,xnew無意義,d2i為DER解碼函數,in為bio數據,x為數據類型,返回值為解碼后的結果。
        h.void *ANS1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
        將in只想的文件進行DER解碼,器內部調用了ASN1_d2i_b函數,用法與ASN1_d2i_b類似。
        i.int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
        將ASN1數據結構DER編碼,并將結果寫入bio
        j.int ASN1_i2d_fp(i2d_of_void *i2d, d2i_of_void *d2i, char *x)
        ASN1數據復制。x為ASN1內部數據結構,本函數先將x通過i2d將他變成DER編碼,然后用d2i在DERb編碼結果
        k.ASN1_ENUMERATED_set
        設置ASN1_ENUMERATED的值
        l.ASN1_ENUMERATED_get
        獲取ASN1_ENUMERTED的值。
        m.BIGNUM * ANS1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
        將ASN1_ENUMERATED類型轉換為BN大數類型。此函數調用BN_bin2bn函數獲取bn,如果ai->type表明他在調用BN_set_negative設置bn成負數。
        n.int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len; int indent, int dump)
        本函數用于將pp和len指明的DER編碼值寫在BIO中,其中indent和dump用于設置打印的格式。
        o.int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_LAGOR *algor2, ANS1_BIT_STRING *data, EVP_PKEY *pkey, const EVP_MD *type)
        對ASN1數據類型簽名。i2d為ASN1數據的DER方法,signature用于存放簽名結果,data為ASN1數據指針,pkey指明簽名密鑰,type為摘要算法,algor1和algor2無用,可全為NULL.簽名時,先將ASN1數據DER編碼,然后摘要,最后簽名運算
        p.ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *str)
        ASN1_STRING類型拷貝。內部申請空間,需要用戶調用ASN1_STRING_free釋放該空間
        q.int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b)
        ASN1_STRING比較.ossl_typ.h中絕大多數ASN1基本類型都定義 ASN1_STRING,所以,此函數比較通用。
        r.unsigned char *ASN1_STRING_data(ASN1_STRING *x)
        獲取ASN1_STRING數據存放地址,即ASN1_STRING數據結構中data地址。
        s.int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
        設置ASN1字符串類型的值。str為ASN1_STRING地址,_data為設置值的首地址,len為被設置值的長度。
        t.ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
        根據nid來查找ASN1_STRING_TABLE表。此函數先查找標準表tbl_standard,再查找擴展表stable。
        u.ASN1_STRING *ASN1-STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in , int inlen, int inform, int nid)
        根據nid和輸入值獲取對應的ASN1_STIRNG類型
        static const ASN1_STRING_TABLE tbl_standard[] = {
        {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
        {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
        {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
        {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
        {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
        {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE,
        0},
        {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING,
        STABLE_NO_MASK},
        {NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
        {NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
        {NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
        {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
        {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
        {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
        {NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING,
        STABLE_NO_MASK},
        {NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
        {NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
        {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
        {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
        {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
        {NID_rfc822Mailbox, 1, ub_rfc822_mailbox, B_ASN1_IA5STRING,
        STABLE_NO_MASK},
        {NID_jurisdictionCountryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
        {NID_INN, 1, 12, B_ASN1_NUMERICSTRING, STABLE_NO_MASK},
        {NID_OGRN, 1, 13, B_ASN1_NUMERICSTRING, STABLE_NO_MASK},
        {NID_SNILS, 1, 11, B_ASN1_NUMERICSTRING, STABLE_NO_MASK},
        {NID_countryCode3c, 3, 3, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
        {NID_countryCode3n, 3, 3, B_ASN1_NUMERICSTRING, STABLE_NO_MASK},
        {NID_dnsName, 0, -1, B_ASN1_UTF8STRING, STABLE_NO_MASK}
        };
        v.void ASN1_STRING_set_default_mask(unsigned long mask)
        設置ASN1_STRING_set_by_NID函數返回的ASN1_STRING類型。
        w.int ASN1_STRING_set_defualt_mask_asc(char *p)
        設置ASN1_STRING_set_by_NID函數返回ASN1_STRING類型。字符串p可以的值由:nombstr, pkix\utf8only和defualt
        x.int ASN1_STRING_TABLE_add(int nid, long minsize, long maxsize, usngiend long mask, unsigned long flags)
        添加擴展ASN1_STRING_TABLE項
        y.void ASN1_STRING_TABLE_cleanup(void)
        清除用戶自建的擴展ASN1_STRING_TBALE表
        z.int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
        將整數轉換為ASCII碼,放在BIO中。
         
        a1.int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
        type不起作用,將ASN1_STRING轉換為ASCII碼
        b1.OBJ_bsearch
        用于從排序好的數據結構地址數組中用二分法查找數據。
        c1.OBJ_create
        根據oid以及名稱信息生成一個你不的object
        d1.OBJ_NAME_add
        OBJ_NAME_cleanup
        OBJ_NAME_get
        OBJ_NAME_init
        OBJ_NAME_remove
        OBJ_NAME_new_index
        OBJ_NAME_do_all
        OBJ_NAME_do_all_sorted
        OBJ_NAME函數用于根據名字獲取對稱算法或者摘要算法。
        e1. int OBJ_new_nid(int num)
        此函數將內部的new_nid加num,返回原nid
        f1.const char *OBJ_nid2ln(int n)
        根據nide得到對象的描述
        g1.OBJ_nid2obj
        根據nid得到對象
        h1.const char *OBJ_nid2sn(int n)
        根據nid得到的對象的sn(簡稱)
        i1.OBJ_nid2obj
        根據nid得到對象
        j1.const char *OBJ_nid2sn(int n)
        根據nid得到對象
        k1.int OBJ_obj2nid(const ASN1_OBJECT *a)
        根據對象獲取其nid;
        l1 int OBJ_obj2nid(const ASN1_OBJECT *a)
        根據對象獲取器nid;
        m1 OBJ_obj2txt
        根據對象獲取對象說明或者nid
        n1.OBJ_txt2obj
        根據sn或者ln得到的對象
         
        13.8 屬性證書編碼
        對屬性證書(x509v4)編碼
        typedef struct X509V4_VALID_st
        {
        ASN1_GENERALIZEDTIME *notBefor;
        ASN1_GENERALIZEDTIME *notAfer;
        }X509V4_VALID;
        DECLARE_ASN1_FUNCTIONS(X509V4_VALID)
         
        typedef struct ISSUERSERIAL_st
        {
        GENERAL_NBAMES *issuer;
        ASN1_INTEGER *subjectSN;
        ASN1_BIT_STRING *issuerUID;
        } ISSUERSERIAL;
        DECLARE_ASN1_FUNCTIONS(ISSUERSERIAL)
         
        typedef struct OBJDIGEST_st
        {
        ASN1_ENUMERATE *digestType;
        ASN1_OBJECT *otherType;
        X509_ALGOR *digestAlg;
        ASN1_BIT_STRING *digestBit;
        } OBJDIGEST;
        DECLARE_ASN1_FUNCTIONS(OBJDIGEST)
         
        typedef struct ACHOLDER_st
        {
        ISSUERSERIAL *baseCertificateID;
        GENERAL_NAMES *entiyName
        OBJDIGEST *objDigest;
        }ACHOLDER;
        DECLARE_ASN1_FUNCTIONS(ACHOLDER)
         
        typedef struct V2FORM_st
        {
        GENERAL_NAMES *entiyName;
        issuerserial *baseCertificateID;
        OBJDIGEST *objDigest;
        }V2FORM;
        DECLARE_ASN1_FUNCTIONS(V2FORM)
         
        typedef struct ACISSUER_st
        {
        int type;
        union
        {
        V2FORM *v2Form;
        }form;
        } ACISSUER;
        DECLARE_ASN1_FUNCTIONS(ACISSUER)
         
         
        ASN1_SEQUENCE(ISSUERSERIAL) = {
        asn1_simple(issuerserial, ISSUER, GENERAL_NAMES),
        ASN1_SIMPLE(ISSUERSERIAL, subjectSN, ASN1_INTEGER)
        ASN1_OPT(ISSUERSERIAL, isserUID, ASN1_BIT_STIRNG)
        }ASN1_SEQUENCE_END(ISSUERSERIAL)
        IMPLEMENT_ASN1_FUNCTIONS(ISSUERSERIAL)
         
        ASN1_SEQUENCE(OBJDIGEST) = {
        ASN1_SIMPLE(OBJDIGEST, digestType, ASN1_ENUMERATED),
        ASN1_OPT(OBJDIGEST, otherType, ASN1_OBJECT),
        ASN1_SIMPLE(OBJDIGEST, digestAlg, X509_ALGOR)
        ASN1_SIMPLE(OBJDIGEST, digestBit, ASN1_BIT_STRING)
        } ASN1_SEQUENEC_END(OBJDIGEST)
        IMPLEMENT_ASN1_FUNCTIONS(OBJDIGEST)
         
        ASN1_SEQUENCE(X509V4_ALID) = {
        ASN1_SIMPLE(X509V4_VALID, notBefore, ASN1_GENERALIZEDTIME)
        ASN1_SIMPLE(X509V4_VALID, notAfer, ASN1_GENERALIZEDTIME)
        }IMPLEMENT_ASN1_FUNCTIONS(X509V4_VALID)\
         
        ASN1_SEQUENCE(X5409V4_CINF) = {
        ASN1_SIMPLE(X509V4_CINF, version, ASN1_INTEGER)
        ASN1_SIMPLE(X509V4_CINF, holder, ACHOLDER)
        ASN1_SIMPLE(X509V4_CINF, issuer, ACISSUER)
        ASN1_SIMPLE(X509V4_CINF, signature, ACISSUER)
        ASN1_SIMPLE(X509V4_CINF, serialNumber, ASN1_INTEGER)
        ASN1_SIMPLE(X509V4_CINF, X509V4_VALID)
        ASN1_SIMPLE(X509V4_CINF,attributes, X509_ATTRIBUTE)
        ASN1_SIMPLE(X509V4_CINF, issuerUID, ASN1_BIT_STRING)
        ASN1_SIMPLE(X509V4_CINF, EXTENSIONS, x509_extension
        }ASN1_SEQUENCE_END(X509V4_CINF)
        IMPLEMENT_ASN1_FUNCTIONS(X509V4_CINF)
         
        ASN1_SEQUENCE(X509V4) = {
        ASN1_SIMPLE(X509V4, cert_info, X509V4_CINF)
        ASN1_SIMPLE(X509V4, sig_alg, X509_ALGOR)
        ASN1_SIMPLE(X509V4, signature, ASN1_BIT_STRING)
        }ASN1_SEQUENCE_END(X5509V4)


        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。



        關鍵詞: asn1

        技術專區

        關閉
        主站蜘蛛池模板: 财经| 桂阳县| 班玛县| 故城县| 巴林左旗| 鄂尔多斯市| 周口市| 邯郸市| 壶关县| 金阳县| 甘谷县| 卢湾区| 永泰县| 武穴市| 荆门市| 咸宁市| 安丘市| 濮阳市| 永康市| 逊克县| 台南县| 宣武区| 庆阳市| 上思县| 塔河县| 峨边| 东源县| 无为县| 屯门区| 博兴县| 肇州县| 波密县| 汾西县| 拉萨市| 股票| 上栗县| 合川市| 久治县| 车险| 舒兰市| 瑞安市|