版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、.转 SSL连接建立过程分析 42.13 SSL_connect SSL_connect这个函数完成SSL协商的客户端操作:/* ssl/ssl_lib.c */int SSL_connectSSL *s if s->handshake_func = 0 /* Not properly initialized yet */ SSL_set_connect_states; returns->method->ssl_connects; 其中SSL_set_connect_states
2、函数初始化SSL协商处理:void SSL_set_connect_stateSSL *s / 客户端 s->server=0; s->shutdown=0;/ 初始化客户端状态值 s->state=SSL_ST_CONNECT|SSL_ST_BEFORE;/ 握手函数即是ssl_connect函数 s->handshake_func=s->method->ssl_connect; /* clear the current cipher */ 去除SSL读写加密算法上下文 ssl_clea
3、r_cipher_ctxs; 因此最重要的就是ssl_connect这两个成员函数,是前面SSLv23_client_method函数中定义的,如对于SSLv23方法,处理函数分别为ssl23_connect函数,其它SSLv2和SSLv3方法分别对应ssl2_connect和ssl3_connect,后两者就没有协商过程了,ssl23_connect实际在协商确定协议版本后也是调用ssl23_connect。掌握了服务器端的accept过程,理解客户端的connect过程就简单了。/* ssl/s23_clnt.c */int ssl23_connectSSL *s
4、160;BUF_MEM *buf=NULL; unsigned long Time=timeNULL; void *cbconst SSL *ssl,int type,int val=NULL; int ret= -1; int new_state,state;/ 和服务器端一样进行根本的初始化 RAND_add&Time,sizeofTime,0; ERR_clear_error; clear_sys_error; if s->info_callback != NULL cb=
5、s->info_callback; else if s->ctx->info_callback != NULL cb=s->ctx->info_callback; s->in_handshake+; if !SSL_in_inits | SSL_in_befores SSL_clears; for ; state=s->state;/ 在SSL_set_connect_state中s->state被初始化为SSL_ST_CONNECT|S
6、SL_ST_BEFORE switchs->state case SSL_ST_BEFORE: case SSL_ST_CONNECT: case SSL_ST_BEFORE|SSL_ST_CONNECT: case SSL_ST_OK|SSL_ST_CONNECT:/ 进行根本初始化,分配缓冲区 if s->session != NULL
7、60; SSLerrSSL_F_SSL23_CONNECT,SSL_R_SSL23_DOING_SESSION_ID_REUSE; ret= -1; goto end; s->server=0; if cb != NULL cbs,SSL_CB_HANDSHAKE_START,1; /* s->version=TLS1_V
8、ERSION; */ s->type=SSL_ST_CONNECT; if s->init_buf = NULL if buf=BUF_MEM_new = NULL ret= -1; goto end;
9、 if !BUF_MEM_growbuf,SSL3_RT_MAX_PLAIN_LENGTH ret= -1; goto end; s->init_buf=buf; buf=NULL; &
10、#160; if !ssl3_setup_bufferss ret= -1; goto end; ssl3_init_finished_macs;/ SSL客户端状态转为准备发送HELLO信息 s->state=SSL23_ST_CW_CLNT_HELLO_A; s->ctx->stats.sess_connect+; s->init_num=0; bre
11、ak; case SSL23_ST_CW_CLNT_HELLO_A: case SSL23_ST_CW_CLNT_HELLO_B:/ 发送客户端的HELLO信息 s->shutdown=0; ret=ssl23_client_hellos; if ret <= 0 goto end;/ 转为准备接收服务器端的HELLO状态 s->state=SSL23_ST_CR_SRVR_HELLO_A;
12、0; s->init_num=0; break; case SSL23_ST_CR_SRVR_HELLO_A: case SSL23_ST_CR_SRVR_HELLO_B:/ 读取服务器端的HELLO信息,完成SSL握手协商 ret=ssl23_get_server_hellos; if ret >= 0 cb=NULL; goto end; /*
13、break; */ default: SSLerrSSL_F_SSL23_CONNECT,SSL_R_UNKNOWN_STATE; ret= -1; goto end; /* break; */ if s->debug voidBIO_flushs->wbio; if cb != NULL && s->state != st
14、ate new_state=s->state; s->state=state; cbs,SSL_CB_CONNECT_LOOP,1; s->state=new_state; end: s->in_handshake-; if buf != NULL BUF_MEM_freebuf; if cb
15、 != NULL cbs,SSL_CB_CONNECT_EXIT,ret; returnret; ssl23_client_hello函数发送客户端的HELLO信息:/* ssl/s23_clnt.c */static int ssl23_client_helloSSL *s unsigned char *buf; unsigned char *p,*d; int i,ch_len; int ret; buf=unsigned char *s->init_buf->d
16、ata; if s->state = SSL23_ST_CW_CLNT_HELLO_A / 准备发送HELLO, 构造发送缓冲区的数据,数据格式见SSL_accept一节中的说明 p=s->s3->client_random; RAND_pseudo_bytesp,SSL3_RANDOM_SIZE; /* Do the message type and length last */ d= &buf2;/ p指向SSL握手记录头11字节长后的第一字节处
17、 p=d+9;/ 消息类型 *d+=SSL2_MT_CLIENT_HELLO;/ 填写客户端版本号 if !s->options & SSL_OP_NO_TLSv1 *d+=TLS1_VERSION_MAJOR; *d+=TLS1_VERSION_MINOR; s->client_version=TLS1_VERSION;
18、160;else if !s->options & SSL_OP_NO_SSLv3 *d+=SSL3_VERSION_MAJOR; *d+=SSL3_VERSION_MINOR; s->client_version=SSL3_VERSION; else if !s->options & SSL_OP_NO_SSLv2
19、160; *d+=SSL2_VERSION_MAJOR; *d+=SSL2_VERSION_MINOR; s->client_version=SSL2_VERSION; else SSLerrSSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_PROTOCOLS_AVAILABLE; return-1;
20、;/ 填写cipher_specs信息 /* Ciphers supported */ i=ssl_cipher_list_to_bytess,SSL_get_cipherss,p; if i = 0 /* no ciphers */ SSLerrSSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE; return-1;
21、 s2ni,d; p+=i;/ 填写会话ID /* put in the session-id, zero since there is no * reuse. */ s2n0,d; if s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG ch_len=SSL2_CHALLENGE_LENGTH; else ch
22、_len=SSL2_MAX_CHALLENGE_LENGTH;/ 填写挑战信息 /* write out sslv2 challenge */ if SSL3_RANDOM_SIZE < ch_len i=SSL3_RANDOM_SIZE; else i=ch_len; s2ni,d; memset&s->s3->client_random0,0,SSL3_RANDOM_SIZE;
23、 RAND_pseudo_bytes&s->s3->client_randomSSL3_RANDOM_SIZE-i,i; memcpyp,&s->s3->client_randomSSL3_RANDOM_SIZE-i,i; p+=i;/ 数据长度 i= p- &buf2; buf0=i>>8&0xff|0x80; buf1=i&0xff;/ 数据完成,状态转为HELLO B准备发送
24、0;s->state=SSL23_ST_CW_CLNT_HELLO_B; /* number of bytes to write */ s->init_num=i+2; s->init_off=0; ssl3_finish_macs,&buf2,i; /* SSL3_ST_CW_CLNT_HELLO_B */ 发送HELLO数据 ret = ssl23_write_bytess; if ret >= 2
25、0;if s->msg_callback s->msg_callback1, SSL2_VERSION, 0, s->init_buf->data+2, ret-2, s, s->msg_callback_arg; /* CLIENT-HELLO */ return ret; ssl23_get_server_hello接收服务器端的回应,识别服务器的SSL版本,最后再相应调用ssl2_connect或ssl3_connect函数。/* ssl/s23_clnt.c */static int ssl23_get
26、_server_helloSSL *s char buf8; unsigned char *p; int i; int n;/ 读7字节的服务器端数据 n=ssl23_read_bytess,7; if n != 7 returnn; p=s->packet; memcpybuf,p,n; if p0 & 0x80 && p2 = SSL2_MT_SERVER_HELLO && p5 = 0x00 && p6
27、= 0x02 / 服务器是SSL2版本#ifdef OPENSSL_NO_SSL2 SSLerrSSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL; goto err;#else /* we are talking sslv2 */ /* we need to clean up the SSLv3 setup and put in the * sslv2 stuff. */ int
28、 ch_len; if s->options & SSL_OP_NO_SSLv2 SSLerrSSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL; goto err; / 初始化SSL结构中的SSL2支持,ssl_connect将为ssl2_connect if s->s2 = NULL &
29、#160; if !ssl2_news goto err; else ssl2_clears; if s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG ch_len=SSL2_CHALLENGE_LENGTH; else ch_len=SSL2_MAX_CHALLENGE_LENGTH;&
30、#160; /* write out sslv2 challenge */ i=SSL3_RANDOM_SIZE < ch_len ?SSL3_RANDOM_SIZE:ch_len; s->s2->challenge_length=i; memcpys->s2->challenge, &s->s3->client_randomSSL3_RANDOM_SIZE-i,i; if s-&
31、gt;s3 != NULL ssl3_frees; if !BUF_MEM_grow_cleans->init_buf, SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER SSLerrSSL_F_SSL23_GET_SERVER_HELLO,ERR_R_BUF_LIB; goto err; s->state=SSL2_ST_GET_SERVER
32、_HELLO_A; if !s->client_version = SSL2_VERSION /* use special padding SSL 3.0 draft/RFC 2246, App. E.2 */ s->s2->ssl2_rollback=1; /* setup the 5 bytes we have read so we get them from * the sslv2 buffer */ s->
33、rstate=SSL_ST_READ_HEADER; s->packet_length=n; s->packet= &s->s2->rbuf0; memcpys->packet,buf,n; s->s2->rbuf_left=n; s->s2->rbuf_offs=0; /* we have already written one */ s->s2->write_seq
34、uence=1; s->method=SSLv2_client_method; s->handshake_func=s->method->ssl_connect;#endif else if p0 = SSL3_RT_HANDSHAKE && p1 = SSL3_VERSION_MAJOR && p2 = SSL3_VERSION_MINOR | p2 = TLS1_VERSIO
35、N_MINOR && p5 = SSL3_MT_SERVER_HELLO / 服务器版本为SSL3或TLS1,ssl_connect将为ssl3_connect /* we have sslv3 or tls1 */ if !ssl_init_wbio_buffers,1 goto err; /* we are in this state */ s->state=SSL3_ST_CR_SRVR_HELLO_A; /*
36、put the 5 bytes we have read into the input buffer * for SSLv3 */ s->rstate=SSL_ST_READ_HEADER; s->packet_length=n; s->packet= &s->s3->rbuf.buf0; memcpys->packet,buf,n; s->s3->rbuf.left=n; s->
37、;s3->rbuf.offset=0; if p2 = SSL3_VERSION_MINOR && !s->options & SSL_OP_NO_SSLv3 s->version=SSL3_VERSION; s->method=SSLv3_client_method; else if p2 = TLS1_VERSION_MINOR
38、 && !s->options & SSL_OP_NO_TLSv1 s->version=TLS1_VERSION; s->method=TLSv1_client_method; else SSLerrSSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTE
39、D_PROTOCOL; goto err; s->handshake_func=s->method->ssl_connect; else if p0 = SSL3_RT_ALERT && p1 = SSL3_VERSION_MAJOR && p2 = SSL3_VERSION_MINOR | p2 =
40、TLS1_VERSION_MINOR && p3 = 0 && p4 = 2 / SSL告警信息 void *cbconst SSL *ssl,int type,int val=NULL; int j; /* An alert */ if s->info_callback != NULL cb=s->info_callback; else
41、if s->ctx->info_callback != NULL cb=s->ctx->info_callback; i=p5; if cb != NULL j=i<<8|p6; cbs,SSL_CB_READ_ALERT,j; s->rwstate=SSL_NOTHING; SSL
42、errSSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p6; goto err; else SSLerrSSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNKNOWN_PROTOCOL; goto err; s->init_num=0; /* Since, if we are sending a ssl23 client hello, we are
43、not * reusing a session-id */ if !ssl_get_new_sessions,0 goto err; s->first_packet=1;/ 递归调用SSL_connect,实际将执行ssl2_connect或ssl3_connect returnSSL_connects;err: return-1; 举例ssl3_conect函数定义如下,ssl2_connect就不分析了:/* ssl/s3_clnt.c */int ssl3_connectSSL *s
44、160; BUF_MEM *buf=NULL; unsigned long Time=timeNULL,l; long num1; void *cbconst SSL *ssl,int type,int val=NULL; int ret= -1; int new_state,state,skip=0;/ 对SSL3连接的初始化 RAND_add&Time,sizeofTime,0; ERR_clear_error; clear_sys_error; if s->info_call
45、back != NULL cb=s->info_callback; else if s->ctx->info_callback != NULL cb=s->ctx->info_callback; s->in_handshake+; if !SSL_in_inits | SSL_in_befores SSL_clears; for ; state=s->state; switchs->
46、state case SSL_ST_RENEGOTIATE:/ 重协商的话从头开场, 注意break是注释掉的 s->new_session=1; s->state=SSL_ST_CONNECT; s->ctx->stats.sess_connect_renegotiate+; /* break */ 初始状态应该是SSL_ST_BEFORE|SSL_ST_CONNECT
47、0; case SSL_ST_BEFORE: case SSL_ST_CONNECT: case SSL_ST_BEFORE|SSL_ST_CONNECT: case SSL_ST_OK|SSL_ST_CONNECT:/ server=0表示是客户端 s->server=0; if cb != NULL cbs,SSL_CB_HANDSHAKE_START,1;/ 假设本地版本不是SSL3那么出错 if s-&g
48、t;version & 0xff00 != 0x0300 SSLerrSSL_F_SSL3_CONNECT, ERR_R_INTERNAL_ERROR; ret = -1; goto end; /* s->version=SSL3_VERSION; */ s->type=SSL
49、_ST_CONNECT;/ 初始化连接缓冲区 if s->init_buf = NULL if buf=BUF_MEM_new = NULL ret= -1; goto end; if
50、 !BUF_MEM_growbuf,SSL3_RT_MAX_PLAIN_LENGTH ret= -1; goto end; s->init_buf=buf; buf=NULL; if
51、!ssl3_setup_bufferss ret= -1; goto end; /* setup buffing BIO */ if !ssl_init_wbio_buffers,0 ret= -1; goto end; /* don't push the buffering BIO quite yet */ ssl3_init_finished_macs;/ 准备发送HELLO信息 s->state=SSL
52、3_ST_CW_CLNT_HELLO_A; s->ctx->stats.sess_connect+; s->init_num=0; break; case SSL3_ST_CW_CLNT_HELLO_A: case SSL3_ST_CW_CLNT_HELLO_B:/ 该状态发送客户端SSL3信息 s->shutdown=0; ret=ssl3_client_h
53、ellos; if ret <= 0 goto end;/ 发送成功,状态转为准备接收服务器的HELLO回应 s->state=SSL3_ST_CR_SRVR_HELLO_A; s->init_num=0; /* turn on buffering for the next lot of output */ if s->bbio != s->wbio
54、s->wbio=BIO_pushs->bbio,s->wbio; break; case SSL3_ST_CR_SRVR_HELLO_A: case SSL3_ST_CR_SRVR_HELLO_B:/ 该状态下接收服务器发送的HELLO信息 ret=ssl3_get_server_hellos; if ret <= 0 goto end; if s->hit/ 假设是reuse的连接,状
55、态转为接收结束 s->state=SSL3_ST_CR_FINISHED_A; else/ 否那么状态转为准备接收服务器的证书 s->state=SSL3_ST_CR_CERT_A; s->init_num=0; break; case SSL3_ST_CR_CERT_A: case SSL3_ST_CR_CERT_B:/ 该状态下接收服务器
56、发送的证书 /* Check if it is anon DH */ if !s->s3->tmp.new_cipher->algorithms & SSL_aNULL ret=ssl3_get_server_certificates; if ret <= 0 goto end;
57、0;else skip=1;/ 状态转为接收密钥交换信息 s->state=SSL3_ST_CR_KEY_EXCH_A; s->init_num=0; break; case SSL3_ST_CR_KEY_EXCH_A: case SSL3_ST_CR_KEY_EXCH_B:/ 该状态下接收密钥交换信息 ret=ssl3_get_key_exchanges;&
58、#160; if ret <= 0 goto end;/ 状态转为接收证书请求 s->state=SSL3_ST_CR_CERT_REQ_A; s->init_num=0; /* at this point we check that we have the * required stuff from the server */ if !ssl3_check_cert_and_algo
59、rithms ret= -1; goto end; break; case SSL3_ST_CR_CERT_REQ_A: case SSL3_ST_CR_CERT_REQ_B:/ 该状态下接收服务器的证书请求 ret=ssl3_get_certificate_requests;
60、; if ret <= 0 goto end; s->state=SSL3_ST_CR_SRVR_DONE_A; s->init_num=0; break; case SSL3_ST_CR_SRVR_DONE_A: case SSL3_ST_CR_SRVR_DONE_B:/ 该状态下接收服务器信息结束 ret=ssl3_get_server_dones;
61、if ret <= 0 goto end; if s->s3->tmp.cert_req/ 发送客户端证书 s->state=SSL3_ST_CW_CERT_A; else/ 发送密钥交换信息 s->state=SSL3_ST_CW_KEY_EXCH_A; s->init_num=0; break; case S
62、SL3_ST_CW_CERT_A: case SSL3_ST_CW_CERT_B: case SSL3_ST_CW_CERT_C: case SSL3_ST_CW_CERT_D:/ 该状态下发送客户端证书 ret=ssl3_send_client_certificates; if ret <= 0 goto end;/ 状态转为发送密钥交换信息 s->state=SSL3_ST_CW_KEY_EXCH_A;
63、; s->init_num=0; break; case SSL3_ST_CW_KEY_EXCH_A: case SSL3_ST_CW_KEY_EXCH_B:/ 该状态下发送密钥交换信息 ret=ssl3_send_client_key_exchanges; if ret <= 0 goto end;/ 加密算法 l=s->s3->tmp.new_cipher->a
64、lgorithms; /* EAY EAY EAY need to check for DH fix cert * sent back */ /* For TLS, cert_req is set to 2, so a cert chain * of nothing is sent, but no verify packet is sent */ if s->s3->tmp.cert_req = 1
65、 / 发送证书验证 s->state=SSL3_ST_CW_CERT_VRFY_A; else / TLS, 不用发送证书认证信息,直接转为修改算法状态 s->state=SSL3_ST_CW_CHANGE_A; s->s3->change_cipher_spec=0;
66、60; s->init_num=0; break; case SSL3_ST_CW_CERT_VRFY_A: case SSL3_ST_CW_CERT_VRFY_B:/ 该状态发送证书验证信息 ret=ssl3_send_client_verifys; if ret <= 0 goto end;/ 状态转为发送修改算法信息 s->
67、state=SSL3_ST_CW_CHANGE_A; s->init_num=0; s->s3->change_cipher_spec=0; break; case SSL3_ST_CW_CHANGE_A: case SSL3_ST_CW_CHANGE_B:/ 该状态下发送修改算法信息 ret=ssl3_send_change_cipher_specs,
68、;SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B; if ret <= 0 goto end;/ 状态转为发送结束 s->state=SSL3_ST_CW_FINISHED_A; s->init_num=0;/ 设置会话加密算法 s->session->cipher=s->s3->tmp.new_cipher; if s->s3->tmp.n
69、ew_compression = NULL s->session->compress_meth=0; else s->session->compress_meth= s->s3->tmp.new_compression->id; if !s->method->ssl3_enc->setup_key_blocks
70、; ret= -1; goto end; if !s->method->ssl3_enc->change_cipher_states, SSL3_CHANGE_CIPHER_CLIENT_WRITE ret= -1;
71、160; goto end; break; case SSL3_ST_CW_FINISHED_A: case SSL3_ST_CW_FINISHED_B:/ 该状态下发送协商结束信息 ret=ssl3_send_finisheds, SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B, s
72、->method->ssl3_enc->client_finished_label, s->method->ssl3_enc->client_finished_label_len; if ret <= 0 goto end;/ 转为刷新写缓冲状态 s->state=SSL3_ST_CW_FLUSH; /* clear flags */ s->s3->fla
73、gs&= SSL3_FLAGS_POP_BUFFER; if s->hit / 假设是reuse的会话, FLUSH后的下一个状态转为协商成功 s->s3->tmp.next_state=SSL_ST_OK; if s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED
74、 s->state=SSL_ST_OK; s->s3->flags|=SSL3_FLAGS_POP_BUFFER; s->s3->delay_buf_pop_ret=0; else / 否那么状态转为准备接收服务器的协商
75、结束信息 s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A; s->init_num=0; break; case SSL3_ST_CR_FINISHED_A: case SSL3_ST_CR_FINISHED_B:/ 该状态接收服务器发送的协商结束信息 ret=ssl3_get_finisheds,S
76、SL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B; if ret <= 0 goto end; if s->hit/ 假设会话是reuse的,状态转为发送算法 s->state=SSL3_ST_CW_CHANGE_A; else/ 否那么协商成功 s->state=SSL_ST_OK; s->init_num=0; break; case SSL3_ST_CW_FLUSH:/ 该状态下刷新写缓冲区 /* number of bytes to be flushed */ num1=BIO_ctrls->wbi
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 家禽饲养员安全生产基础知识水平考核试卷含答案
- 无人机驾驶员班组管理评优考核试卷含答案
- 玻璃钢制品拉挤工操作规程评优考核试卷含答案
- 工业固体废物处理处置工安全行为考核试卷含答案
- 蜡油渣油加氢工安全宣传知识考核试卷含答案
- 服装制版师安全知识水平考核试卷含答案
- 藏药调理师复测测试考核试卷含答案
- 铸件清理工诚信道德测试考核试卷含答案
- 碳五石油树脂装置操作工技术实务知识考核试卷含答案
- 部编版小学英语六年级下册第2单元课后练习题及答案
- 科瑞智库:2026汉诺威国际车展全景洞察与趋势研判报告
- 2026年7月劳动关系协调师三级模拟试题+参考答案
- 2026事业单位工勤技能-吉林-吉林仓库管理员二级(技师)历年参考题库含答案详解
- T/CAIEC 084-2025城镇排水管道检测与评估技术规程
- 2026新版医院安全风险告知卡大全
- 【《均值不等式在初等数学中的应用研究》6500字(论文)】
- 软件项目立项申请书
- IEC 61800-3-2023 中文版(可调速电力传动系统 第 3 部分:电磁兼容性要求及其特定试验方法)
- 2026人教版四年级数学上册第七单元第1课《数与运算》课件
- 2026年地产运营AI 解决方案合同
- 辣椒基质育苗操作指引
评论
0/150
提交评论