1. /*
  2. * session_key - generate session key
  3. *
  4. * This routine generates a session key from the source address,
  5. * destination address, key ID and private value. The value of the
  6. * session key is the MD5 hash of these values, while the next key ID is
  7. * the first four octets of the hash.
  8. *
  9. * Returns the next key ID or 0 if there is no destination address.
  10. */
  11. keyid_t
  12. session_key(
  13. sockaddr_u *srcadr, /* source address */
  14. sockaddr_u *dstadr, /* destination address */
  15. keyid_t keyno, /* key ID */
  16. keyid_t private, /* private value */
  17. u_long lifetime /* key lifetime */
  18. )
  19. {
  20. EVP_MD_CTX ctx; /* message digest context */
  21. u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */
  22. keyid_t keyid; /* key identifer */
  23. u_int32 header[]; /* data in network byte order */
  24. u_int hdlen, len;
  25.  
  26. if (!dstadr)
  27. return ;
  28.  
  29. /*
  30. * Generate the session key and key ID. If the lifetime is
  31. * greater than zero, install the key and call it trusted.
  32. */
  33. hdlen = ;
  34. switch(AF(srcadr)) {
  35. case AF_INET:
  36. header[] = NSRCADR(srcadr);
  37. header[] = NSRCADR(dstadr);
  38. header[] = htonl(keyno);
  39. header[] = htonl(private);
  40. hdlen = * sizeof(u_int32);
  41. break;
  42.  
  43. case AF_INET6:
  44. memcpy(&header[], PSOCK_ADDR6(srcadr),
  45. sizeof(struct in6_addr));
  46. memcpy(&header[], PSOCK_ADDR6(dstadr),
  47. sizeof(struct in6_addr));
  48. header[] = htonl(keyno);
  49. header[] = htonl(private);
  50. hdlen = * sizeof(u_int32);
  51. break;
  52. }
  53. EVP_DigestInit(&ctx, EVP_get_digestbynid(crypto_nid));
  54. EVP_DigestUpdate(&ctx, (u_char *)header, hdlen);
  55. EVP_DigestFinal(&ctx, dgst, &len);
  56. memcpy(&keyid, dgst, );
  57. keyid = ntohl(keyid);
  58. if (lifetime != ) {
  59. MD5auth_setkey(keyno, crypto_nid, dgst, len);
  60. authtrust(keyno, lifetime);
  61. }
  62. DPRINTF(, ("session_key: %s > %s %08x %08x hash %08x life %lu\n",
  63. stoa(srcadr), stoa(dstadr), keyno,
  64. private, keyid, lifetime));
  65. #ifdef DEBUG
  66. if (debug)
  67. printf("session_key:MD5 DIGEST ==== %08x\n",dgst);
  68. #endif
  69.  
  70. return (keyid);
  71. }

以上例程是根据the source address, * destination address, key ID and private value这四者做哈希,下一个密钥ID就是这个哈希值的前四个字节。

同时以上代码展示了,MD5的算法流程,先定义EVP_MD_CTX  ctx,然后定义哈希值的存放地址char * dgst。

  1.  
  1. EVP_DigestInit(&ctx, EVP_get_digestbynid(crypto_nid));
  2. EVP_DigestUpdate(&ctx, (u_char *)header, hdlen);
  3. EVP_DigestFinal(&ctx, dgst, &len);
  1.  

经过以上步骤,再将结果写入dgst中。

如果密钥的生存时间不为0,那么就调用MD5auth_setkey来验证密钥是否是可信任的。

  1. /*
  2. * authistrusted - determine whether a key is trusted
  3. */
  4. int
  5. authistrusted(
  6. keyid_t keyno
  7. )
  8. {
  9. struct savekey *sk;
  10.  
  11. if (keyno == cache_keyid)
  12. return ((cache_flags & KEY_TRUSTED) != );
  13.  
  14. authkeyuncached++;
  15. sk = key_hash[KEYHASH(keyno)];
  16. while (sk != ) {
  17. if (keyno == sk->keyid)
  18. break;
  19. sk = sk->next;
  20. }
  21. if (sk == ) {
  22. authkeynotfound++;
  23. #ifdef DEBUG
  24. if (debug)
  25. printf("authistrusted authkeynotfound++\n");
  26. #endif
  27.  
  28. return ();
  29.  
  30. } else if (!(sk->flags & KEY_TRUSTED)) {
  31. #ifdef DEBUG
  32. if (debug)
  33. printf("authistrusted authkeynotfound++\n");
  34. #endif
  35.  
  36. authkeynotfound++;
  37. return ();
  38. }
  39. return ();
  40. }

如果密钥ID已经被cache,那么密钥就是可信的。否则就根据key_no做哈希找到sk,查看sk的KEY_TRUSTED有没有置位,如果置位说明密钥可信。整个authistrusted返回1。
整个函数的传入参数是一个32位的整形,KEYHASH这个宏取出其中的前6位,然后在key_hash这个数组中找到对应的savekey。

ntp源码解读(一)的更多相关文章

  1. SDWebImage源码解读之SDWebImageDownloaderOperation

    第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...

  2. SDWebImage源码解读 之 NSData+ImageContentType

    第一篇 前言 从今天开始,我将开启一段源码解读的旅途了.在这里先暂时不透露具体解读的源码到底是哪些?因为也可能随着解读的进行会更改计划.但能够肯定的是,这一系列之中肯定会有Swift版本的代码. 说说 ...

  3. SDWebImage源码解读 之 UIImage+GIF

    第二篇 前言 本篇是和GIF相关的一个UIImage的分类.主要提供了三个方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name ----- 根据名 ...

  4. SDWebImage源码解读 之 SDWebImageCompat

    第三篇 前言 本篇主要解读SDWebImage的配置文件.正如compat的定义,该配置文件主要是兼容Apple的其他设备.也许我们真实的开发平台只有一个,但考虑各个平台的兼容性,对于框架有着很重要的 ...

  5. SDWebImage源码解读_之SDWebImageDecoder

    第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...

  6. SDWebImage源码解读之SDWebImageCache(上)

    第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...

  7. SDWebImage源码解读之SDWebImageCache(下)

    第六篇 前言 我们在SDWebImageCache(上)中了解了这个缓存类大概的功能是什么?那么接下来就要看看这些功能是如何实现的? 再次强调,不管是图片的缓存还是其他各种不同形式的缓存,在原理上都极 ...

  8. AFNetworking 3.0 源码解读 总结(干货)(下)

    承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...

  9. AFNetworking 3.0 源码解读 总结(干货)(上)

    养成记笔记的习惯,对于一个软件工程师来说,我觉得很重要.记得在知乎上看到过一个问题,说是人类最大的缺点是什么?我个人觉得记忆算是一个缺点.它就像时间一样,会自己消散. 前言 终于写完了 AFNetwo ...

随机推荐

  1. Android ListView 无法响应onItemClick事件

    当在布局文件中加入了Button.ImageButton.CheckBox.RadioButton等控件(也就是Button或者Checkable的子类控件)的时候,listView是无法响应onIt ...

  2. Spring入门学习(一)

    Spring的主要功能是控制反转和面向切面编程,下面我们就来编写第一个spring的程序来体验一下控制反转 首先是加载配置文件 <?xml version="1.0" enc ...

  3. shell脚本学习(五)

    1.统计文件的行数.单词数.字符数 1)行数: wc -l file cat file | wc -l 2)单词数 wc -w file cat file | wc -w 3)统计字符数 wc -c ...

  4. Caffe+Ubuntu14.04+CUDA7.5 环境搭建(新人向)指南

    序 本文针对想学习使用caffe框架的纯新手,如果文中有错误欢迎大家指出. 由于我在搭建这个环境的时候参考了许多网上的教程,但是没有截图,所以文中图片大多来源于网络. 本文没有安装matlab的步骤, ...

  5. js与jquery实时监听输入框值变化方法

    本文实例讲述了js与jquery实时监听输入框值的oninput与onpropertychange方法.分享给大家供大家参考.具体如下: 最近做过一个项目,需求是下拉框里自动匹配关键字,具体细节是实时 ...

  6. SharePoint 2013 工作流设计之Designer 使用“可视化视图

    转载自:http://www.cnblogs.com/jianyus/p/3406309.html SharePoint 2013增强了工作流功能,而Designer里面也添加了可视化设计视图,也就是 ...

  7. cookie机制和session机制的区别(面试题)

    一.cookie机制和session机制的区别 具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案. 同时我们也看到,由于才服务器端保持状态的 ...

  8. String类中一些常用的函数

    1 CharAt(index) : 通过他的索引来获取元素 @Test public void test1(){ String a="dfjkdjfd134"; for(int i ...

  9. OSI参考模型各层的主要功能

    OSI参考模型将整个通信功能划分为7个层次,其划分的主要原则是: 1网络中各主机有相同的层次 2 不同主机的同等层具有相同的功能 3同一主机内相邻层之间通过接口通信 4 每层可以使用下层提供的服务,并 ...

  10. C++模板之类型与数据绑定

    有时候我们需要将类型与一些数据进行绑定,例如我们一般通过单例,将字符串与一个函数关联(一般称之为注册),之后通过字符串创建相关联的对象 class A { public: static A* Crea ...