




已阅读5页,还剩37页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Openssl源代码的特点:1、 openssl中只有实现而没有调用的函数2、 openssl中各系列的函数都是用宏定义的(因而无法用代码浏览工具找到其定义)用于定义X509的new、free、i2d和d2i函数的宏:1、函数声明DECLARE_ASN1_FUNCTIONS(X509)用于声明函数x509x509.h在openssl中的具体定义如下:asn1asn1.h/* Declare ASN1 functions: the implement macro in in asn1t.h */#define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)#define DECLARE_ASN1_ALLOC_FUNCTIONS(type) DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type)#define DECLARE_ASN1_FUNCTIONS_name(type, name) DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)#define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)#defineDECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) type *d2i_#name(type *a, const unsigned char *in, long len); int i2d_#name(type *a, unsigned char *out); DECLARE_ASN1_ITEM(itname)#defineDECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) type *d2i_#name(type *a, const unsigned char *in, long len); int i2d_#name(const type *a, unsigned char *out); DECLARE_ASN1_ITEM(name)#defineDECLARE_ASN1_NDEF_FUNCTION(name) int i2d_#name#_NDEF(name *a, unsigned char *out);#define DECLARE_ASN1_FUNCTIONS_const(name) DECLARE_ASN1_ALLOC_FUNCTIONS(name) DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name)#define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) type *name#_new(void); void name#_free(type *a);用于函数的实现asn1x_x509.cASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = ASN1_SIMPLE(X509, cert_info, X509_CINF),ASN1_SIMPLE(X509, sig_alg, X509_ALGOR),ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING) ASN1_SEQUENCE_END_ref(X509, X509)IMPLEMENT_ASN1_FUNCTIONS(X509)2、ASN1_SEQUENCE_ref:ASN1_SEQUENCE_ref:asn1asn1t.h#define ASN1_SEQUENCE_ref(tname, cb, lck) static const ASN1_AUX tname#_aux = NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0; ASN1_SEQUENCE(tname)3、ASN1_SEQUENCE用于SEQUENCE,表明下面的编码是一个SEQUENCE。#define ASN1_SEQUENCE(tname) static const ASN1_TEMPLATE tname#_seq_tt #define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)#define ASN1_SEQUENCE_END_name(stname, tname) ;ASN1_ITEM_start(tname) ASN1_ITYPE_SEQUENCE,V_ASN1_SEQUENCE,tname#_seq_tt,sizeof(tname#_seq_tt) / sizeof(ASN1_TEMPLATE),NULL,sizeof(stname),#stname ASN1_ITEM_end(tname)4、ASN1_SEQUENCE_END_ref:#define ASN1_SEQUENCE_END_ref(stname, tname) ;ASN1_ITEM_start(tname) ASN1_ITYPE_SEQUENCE,V_ASN1_SEQUENCE,tname#_seq_tt,sizeof(tname#_seq_tt) / sizeof(ASN1_TEMPLATE),&tname#_aux,sizeof(stname),#stname ASN1_ITEM_end(tname)5、ASN1_ITEM_start:#define ASN1_ITEM_start(itname) const ASN1_ITEM * itname#_it(void) static const ASN1_ITEM local_it = #define ASN1_ITEM_end(itname) ; return &local_it; 6、函数定义IMPLEMENT_ASN1_FUNCTIONS(X509):/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE)/* Use a reference count */#define ASN1_AFLG_REFCOUNT1具体定义如下:asn1asn1t.h/* Macro to implement standard functions in terms of ASN1_ITEM structures */#define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)#define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) stname *fname#_new(void) return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname); void fname#_free(stname *a) ASN1_item_free(ASN1_VALUE *)a, ASN1_ITEM_rptr(itname); #define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) stname *d2i_#fname(stname *a, const unsigned char *in, long len) return (stname *)ASN1_item_d2i(ASN1_VALUE *)a, in, len, ASN1_ITEM_rptr(itname); int i2d_#fname(stname *a, unsigned char *out) return ASN1_item_i2d(ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname); #define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) int i2d_#stname#_NDEF(stname *a, unsigned char *out) return ASN1_item_ndef_i2d(ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname); ASN1_SIMPLE的定义:asn1asn1t.h/* Plain simple type */#define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)/* used to declare other types */#define ASN1_EX_TYPE(flags, tag, stname, field, type) (flags), (tag), offsetof(stname, field),#field, ASN1_ITEM_ref(type) 结构类型定义如下:由上宏定义可得:ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = ASN1_SIMPLE(X509, cert_info, X509_CINF),ASN1_SIMPLE(X509, sig_alg, X509_ALGOR),ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING) ASN1_SEQUENCE_END_ref(X509, X509)可以扩展为:static const ASN1_AUX tname#_aux = NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0; static const ASN1_TEMPLATE tname#_seq_tt= (flags), (tag), offsetof(stname, field),#field, (&(type_it), (flags), (tag), offsetof(stname, field),#field, (&(type_it) , (flags), (tag), offsetof(stname, field),#field, (&(type_it);const ASN1_ITEM * itname#_it(void) static const ASN1_ITEM local_it = ASN1_ITYPE_SEQUENCE,V_ASN1_SEQUENCE,tname#_seq_tt,sizeof(tname#_seq_tt) / sizeof(ASN1_TEMPLATE),&tname#_aux,sizeof(stname),#stname ; return &local_it; 将参数替换如下:static const ASN1_AUX X509_aux = NULL, ASN1_AFLG_REFCOUNT, offsetof(X509, references), CRYPTO_LOCK_X509, x509_cb, 0; static const ASN1_TEMPLATE X509_seq_tt= (0), (0), offsetof(X509, cert_info),cert_info, (&(X509_CINF_it), (0), (0),offsetof(X509, sig_alg),sig_alg, (&(X509_ALGOR_it), (0), (0),offsetof(X509, signature),signature, (&(ASN1_BIT_STRING_it);const ASN1_ITEM * X509_it(void) static const ASN1_ITEM local_it = ASN1_ITYPE_SEQUENCE,V_ASN1_SEQUENCE,X509_seq_tt,sizeof(X509_seq_tt) / sizeof(ASN1_TEMPLATE),X509_aux,sizeof(X509),X509 ; return &local_it; 由以上扩展出来的代码可以看出:上述宏定义是用于初始化X509_aux变量和X509_seq_tt数组变量,以及X509_it函数。另外,X509_CINF_it是由ASN1_SEQUENCE(X509_CINF) = ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER),ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR),ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),ASN1_SIMPLE(X509_CINF, validity, X509_VAL),ASN1_SIMPLE(X509_CINF, subject, X509_NAME),ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3) ASN1_SEQUENCE_END(X509_CINF)IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)中的 ASN1_SEQUENCE_END(X509_CINF)语句定义的,由宏定义可知ASN1_SEQUENCE_END和ASN1_SEQUENCE_END_ref的定义一样。X509_ALGOR_it和ASN1_BIT_STRING_it的定义也同上。一些宏定义:#define ASN1_ITYPE_SEQUENCE0x1new函数的具体实现IMPLEMENT_ASN1_FUNCTIONS(X509)扩展可得:stname *X509_new(void) return (stname *)ASN1_item_new(&(X509_it); void X509_free(stname *a) ASN1_item_free(ASN1_VALUE *)a, (&(X509_it); 目录:asn1tasn_new.cASN1_item_new函数定义:ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)ASN1_VALUE *ret = NULL;if (ASN1_item_ex_new(&ret, it) 0)return ret;return NULL;ASN1_item_ex_new函数:/* Allocate an ASN1 structure */int ASN1_item_ex_new(ASN1_VALUE *pval, const ASN1_ITEM *it)return asn1_item_ex_combine_new(pval, it, 0);asn1_item_ex_combine_new函数:static int asn1_item_ex_combine_new(ASN1_VALUE *pval, const ASN1_ITEM *it,int combine)const ASN1_TEMPLATE *tt = NULL;const ASN1_COMPAT_FUNCS *cf;const ASN1_EXTERN_FUNCS *ef;const ASN1_AUX *aux = it-funcs;ASN1_aux_cb *asn1_cb;ASN1_VALUE *pseqval;int i;if (aux & aux-asn1_cb)asn1_cb = aux-asn1_cb;elseasn1_cb = 0;if (!combine) *pval = NULL;#ifdef CRYPTO_MDEBUGif (it-sname)CRYPTO_push_info(it-sname);#endifswitch(it-itype)case ASN1_ITYPE_EXTERN:ef = it-funcs;if (ef & ef-asn1_ex_new)if (!ef-asn1_ex_new(pval, it)goto memerr;break;case ASN1_ITYPE_COMPAT:cf = it-funcs;if (cf & cf-asn1_new) *pval = cf-asn1_new();if (!*pval)goto memerr;break;case ASN1_ITYPE_PRIMITIVE:if (it-templates)if (!ASN1_template_new(pval, it-templates)goto memerr;else if (!ASN1_primitive_new(pval, it)goto memerr;break;case ASN1_ITYPE_MSTRING:if (!ASN1_primitive_new(pval, it)goto memerr;break;case ASN1_ITYPE_CHOICE:if (asn1_cb)i = asn1_cb(ASN1_OP_NEW_PRE, pval, it);if (!i)goto auxerr;if (i=2)#ifdef CRYPTO_MDEBUGif (it-sname)CRYPTO_pop_info();#endifreturn 1;if (!combine)*pval = OPENSSL_malloc(it-size);if (!*pval)goto memerr;memset(*pval, 0, it-size);asn1_set_choice_selector(pval, -1, it);if (asn1_cb & !asn1_cb(ASN1_OP_NEW_POST, pval, it)goto auxerr;break;case ASN1_ITYPE_NDEF_SEQUENCE:case ASN1_ITYPE_SEQUENCE:if (asn1_cb)i = asn1_cb(ASN1_OP_NEW_PRE, pval, it);if (!i)goto auxerr;if (i=2)#ifdef CRYPTO_MDEBUGif (it-sname)CRYPTO_pop_info();#endifreturn 1;if (!combine)*pval = OPENSSL_malloc(it-size);if (!*pval)goto memerr;memset(*pval, 0, it-size);asn1_do_lock(pval, 0, it);asn1_enc_init(pval, it);for (i = 0, tt = it-templates; i tcount; tt+, i+)pseqval = asn1_get_field_ptr(pval, tt);if (!ASN1_template_new(pseqval, tt)goto memerr;if (asn1_cb & !asn1_cb(ASN1_OP_NEW_POST, pval, it)goto auxerr;break;#ifdef CRYPTO_MDEBUGif (it-sname) CRYPTO_pop_info();#endifreturn 1;memerr:ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);#ifdef CRYPTO_MDEBUGif (it-sname) CRYPTO_pop_info();#endifreturn 0;auxerr:ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);ASN1_item_ex_free(pval, it);#ifdef CRYPTO_MDEBUGif (it-sname) CRYPTO_pop_info();#endifreturn 0;最后选择的选项是:case ASN1_ITYPE_SEQUENCE:if (asn1_cb)i = asn1_cb(ASN1_OP_NEW_PRE, pval, it);if (!i)goto auxerr;if (i=2)#ifdef CRYPTO_MDEBUGif (it-sname)CRYPTO_pop_info();#endifreturn 1;if (!combine)*pval = OPENSSL_malloc(it-size);if (!*pval)goto memerr;memset(*pval, 0, it-size);asn1_do_lock(pval, 0, it);asn1_enc_init(pval, it);for (i = 0, tt = it-templates; i tcount; tt+, i+)pseqval = asn1_get_field_ptr(pval, tt);if (!ASN1_template_new(pseqval, tt)goto memerr;if (asn1_cb & !asn1_cb(ASN1_OP_NEW_POST, pval, it)goto auxerr;break;#ifdef CRYPTO_MDEBUGif (it-sname) CRYPTO_pop_info();#endifreturn 1;memerr:ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);#ifdef CRYPTO_MDEBUGif (it-sname) CRYPTO_pop_info();#endifreturn 0;auxerr:ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);ASN1_item_ex_free(pval, it);#ifdef CRYPTO_MDEBUGif (it-sname) CRYPTO_pop_info();#endifreturn 0;1、x509_cb函数:asn1x_x509.c(84-128)static int x509_cb(int operation, ASN1_VALUE *pval, const ASN1_ITEM *it)X509 *ret = (X509 *)*pval;switch(operation) case ASN1_OP_NEW_POST:ret-valid=0;ret-name = NULL;ret-ex_flags = 0;ret-ex_pathlen = -1;ret-skid = NULL;ret-akid = NULL;#ifndef OPENSSL_NO_RFC3779ret-rfc3779_addr = NULL;ret-rfc3779_asid = NULL;#endifret-aux = NULL;CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret-ex_data);break;case ASN1_OP_D2I_POST:if (ret-name != NULL) OPENSSL_free(ret-name);ret-name=X509_NAME_oneline(ret-cert_info-subject,NULL,0);break;case ASN1_OP_FREE_POST:CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret-ex_data);X509_CERT_AUX_free(ret-aux);ASN1_OCTET_STRING_free(ret-skid);AUTHORITY_KEYID_free(ret-akid);policy_cache_free(ret-policy_cache);#ifndef OPENSSL_NO_RFC3779sk_IPAddressFamily_pop_free(ret-rfc3779_addr, IPAddressFamily_free);ASIdentifiers_free(ret-rfc3779_asid);#endifif (ret-name != NULL) OPENSSL_free(ret-name);break;return 1;函数中无ASN1_OP_NEW_PRE选项,故返回1operation values/* operation values for asn1_cb */#define ASN1_OP_NEW_PRE0#define ASN1_OP_NEW_POST1#define ASN1_OP_FREE_PRE 2#define ASN1_OP_FREE_POST3#define ASN1_OP_D2I_PRE4#define ASN1_OP_D2I_POST 5#define ASN1_OP_I2D_PRE6#define ASN1_OP_I2D_POST 72、asn1_do_lock函数声明:asn1asn1t.hint asn1_do_lock(ASN1_VALUE *pval, int op, const ASN1_ITEM *it);函数定义:asn1tasn_utl.c/* Do reference counting. The value op decides what to do. * if it is +1 then the count is incremented. If op is 0 count is * set to 1. If op is -1 count is decremented and the return value * is the current refrence count or 0 if no reference count exists. */int asn1_do_lock(ASN1_VALUE *pval, int op, const ASN1_ITEM *it)const ASN1_AUX *aux;int *lck, ret;if (it-itype != ASN1_ITYPE_SEQUENCE) & (it-itype != ASN1_ITYPE_NDEF_SEQUENCE)/注1return 0;aux = it-funcs;if (!aux | !(aux-flags & ASN1_AFLG_REFCOUNT)/注2return 0;lck = offset2ptr(*pval, aux-ref_offset);if (op = 0)/注3*lck = 1;return 1;ret = CRYPTO_add(lck, op, aux-ref_lock);#ifdef REF_PRINTfprintf(stderr, %s: Reference Count: %dn, it-sname, *lck);#endif#ifdef REF_CHECKif (ret sname);#endifreturn ret;参数解析:op=0注1处,it-itype=ASN1_ITYPE_SEQUENCE,故if语句内为0,未跳出函数注2处,aux不为NULL,取反为0。另外aux-flags & ASN1_AFLG_REFCOUNT中aux-flags=ASN1_AFLG_REFCOUNT,即ASN1_AFLG_REFCOUNT&ASN1_AFLG_REFCOUNT,即1&1,取反为0。故根据函数判断,函数也未能返回。注3处,op=0,故references=1,函数返回1作用:引用计数加13、offset2ptr此函数用宏定义:asn1tasn_utl.c/* Add offset to addr */#define offset2ptr(addr, offset) (void *)(char *) addr) + offset)aux-ref_offset=offsetof(X509, references)4、asn1_enc_init函数定义:asn1tasn_utl.cvoid asn1_enc_init(ASN1_VALUE *pval, const ASN1_ITEM *it)ASN1_ENCODING *enc;enc = asn1_get_enc_ptr(pval, it);if (enc)enc-enc = NULL;enc-len = 0;enc-modified = 1;enc为NULL,故enc未进行初始化5、asn1_get_enc_ptr函数定义:asn1tasn_utl.cstatic ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE *pval, const ASN1_ITEM *it)const ASN1_AUX *aux;if (!pval | !*pval)return NULL;aux = it-funcs;if (!aux | !(aux-flags & ASN1_AFLG_ENCODING)return NULL;/注1return offset2ptr(*pval, aux-enc_offset);aux-flags & ASN1_AFLG_ENCODING即ASN1_AFLG_REFCOUNT& ASN1_AFLG_ENCODING,也就是1&2,01&10即为0,取反为1aux不为空,取反为空。0|1为1,故在注1处函数返回6、asn1_get_field_ptr函数定义:asn1tasn_utl.c/* Given an ASN1_TEMPLATE get a pointer to a field */ASN1_VALUE * asn1_get_field_ptr(ASN1_VALUE *pval, const ASN1_TEMPLATE *tt)ASN1_VALUE *pvaltmp;if (tt-flags & ASN1_TFLG_COMBINE)return pval;pvaltmp = offset2ptr(*pval, tt-offset);/* NOTE for BOOLEAN types the field is just a plain * int so we cant return int *, so settle for * (int *). */return pvaltmp;#define ASN1_TFLG_COMBINE(0x1item);int ret;if (tt-flags & ASN1_TFLG_OPTIONAL)asn1_template_clear(pval, tt);return 1;/* If ANY DEFINED BY nothing to do */if (tt-flags & ASN1_TFLG_ADB_MASK)*pval = NULL;return 1;#ifdef CRYPTO_MDEBUGif (tt-field_name)CRYPTO_push_info(tt-field_name);#endif/* If SET OF or SEQUENCE OF, its a STACK */if (tt-flags & ASN1_TFLG_SK_MASK)STACK_OF(ASN1_VALUE) *skval;skval = sk_ASN1_VALUE_new_null();if (!skval)ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);ret = 0;goto done;*pval = (ASN1_VALUE *)skval;ret = 1;goto done;/* Otherwise pass it back to the item routine */ret = asn1_item_ex_combine_new(pval, it, tt-flags & ASN1_TFLG_COMBINE);done:#ifdef CRYPTO_MDEBUGif (it-sname)CRYPTO_pop_info();#endifreturn ret;d2i和i2d函数的具体实现在openssl crypto库中,有很多形似i2d_xxx和d2i_xxx的函数,而且用source insight这样的代码浏览工具是没法找到其定义的,在我刚刚接触openssl的时候,着实郁闷了一阵子,就是找不到定义。后来才发现了这一系列函数的来源。原来他们是通过宏定义的方式来实现的。在asn1.h中,有一系列的宏定义,其中DECLARE_ASN1_ENCODE_FUNCTIONS就是用于d2i和i2d的原型。#define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) / type *d2i_#name(type *a, unsigned char *in, long len); / int i2d_#name(type *a, unsigned char *out); / DECLARE_ASN1_ITEM(itname)对于此宏,如果传入参数为x509,那么扩展以后将变为X509 *d2i_x509(type *a, unsigned char *in, long len);int i2d_509(type *a, unsigned char *out);DECLARE_ASN1_ITEM(x509)这就是d2i和i2d的声明,那么函数定义呢?类似的在asn1t.h中,有这样的宏定义。#define IMPLEMENT_ASN1_ENCODE
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 道路雨水管网及配套设施改造更新工程技术方案
- 校园废旧建筑改造方案设计
- 专业盘扣脚手架租赁及配套安装工程合同
- 深圳建筑节能方案设计
- 离婚子女轮流抚养居住环境与设施协议
- 住宅小区物业维修资金管理与使用协议
- 离婚时个人名誉权保护与财产分割协议范本
- 智能制造领域专利代理与标准制定服务合同
- 城市私人土地买卖及配套设施建设合同
- 夫妻财产分割协议中明确赠与子女房产条款
- 基于Java的网上蛋糕预订销售系统的设计与实现
- 成人高考专升本医学综合考试真题及答案
- 可复制的领导力心得
- 《小猪变形记》一年级
- 抗菌药物临床应用指导原则
- MirrorView切换手册模板
- 急救车必备药品和物品 急救车物品药品管理
- GB/T 3253.8-2009锑及三氧化二锑化学分析方法三氧化二锑量的测定碘量法
- GB/T 24720-2009交通锥
- GB/T 15065-2009电线电缆用黑色聚乙烯塑料
- 陈嘉庚生平介绍(中文+英文版)
评论
0/150
提交评论